Pregunta

He creado un entorno de alojamiento WinForms personalizados. Que tiene una caja de herramientas y una PropertyGrid.

Los controles representada en la caja de herramientas se heredan de controles WinForm existentes.

DropDownList Fuente:

public interface IPropertyFilter : ICustomTypeDescriptor
{
    PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection pdc);
    List<string> GetPropertiesToShow();
}

[Serializable]
public class DropDownList : System.Windows.Forms.ComboBox, IPropertyFilter
{
    public DropDownList()
    {
    }

    #region IPropertyFilter Members

    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    EventDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public string GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this;
    }

    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, attributes, true);
        return FilterProperties(pdc);
    }

    PropertyDescriptorCollection System.ComponentModel.ICustomTypeDescriptor.GetProperties()
    {
        PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(this, true);
        return FilterProperties(pdc);
    }

    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return TypeDescriptor.GetDefaultProperty(this, true);
    }

    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public string GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public PropertyDescriptorCollection FilterProperties(PropertyDescriptorCollection pdc)
    {
        // Filter out properties that we do not want to display in PropertyGrid
        return ControlDesignerHelper.GetBrowsableProperties(pdc, GetPropertiesToShow());
    }

    // Determines what properties of this control has to be shown in PropertyGrid
    public List<string> GetPropertiesToShow()
    {
        // get a list of common properties that we want to show for all controls
        List<string> browsableProps = ControlDesignerHelper.GetBasePropertiesToShow();
        // add properties that are specific to this controls
        browsableProps.Add("Items");
        browsableProps.Add("AutoPostBack");
        browsableProps.Add("AppendDataBoundItems");
        browsableProps.Add("DataTextField");
        browsableProps.Add("DataValueField");
        return browsableProps;
    }

    #endregion
}

Me han implementado ICustomTypeDescriptor para filtrar las propiedades que no quiero mostrar en el PropertyGrid.

Problema:

Estoy frente a un problema, mientras que la serialización de valores de las propiedades Enabled y Visible que se heredan de la clase System.Windows.Forms.Control.

WriteProperties Método (BasicDesignerLoader):

private void WriteProperties(XmlDocument document, PropertyDescriptorCollection properties, object value, XmlNode parent, string elementName)
{
    foreach (PropertyDescriptor prop in properties)
    {
        System.Diagnostics.Debug.WriteLine(prop.Name);

        if (prop.ShouldSerializeValue(value))
        {
            string compName = parent.Name;
            XmlNode node = document.CreateElement(elementName);
            XmlAttribute attr = document.CreateAttribute("name");

            attr.Value = prop.Name;
            node.Attributes.Append(attr);

            DesignerSerializationVisibilityAttribute visibility = (DesignerSerializationVisibilityAttribute)prop.Attributes[typeof(DesignerSerializationVisibilityAttribute)];

            switch (visibility.Visibility)
            {
                case DesignerSerializationVisibility.Visible:
                    if (!prop.IsReadOnly && WriteValue(document, prop.GetValue(value), node))
                    {
                        parent.AppendChild(node);
                    }

                    break;

                case DesignerSerializationVisibility.Content:
                    object propValue = prop.GetValue(value);

                    if (typeof(IList).IsAssignableFrom(prop.PropertyType))
                    {
                        WriteCollection(document, (IList)propValue, node);
                    }
                    else
                    {
                        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(propValue, propertyAttributes);

                        WriteProperties(document, props, propValue, node, elementName);
                    }

                    if (node.ChildNodes.Count > 0)
                    {
                        parent.AppendChild(node);
                    }

                    break;

                default:
                    break;
            }
        }
    }
}

Problema # 1:. El método ShouldSerializeValue para la propiedad Enabled y Visible siempre devuelve false

Problema # 2:. Incluso si me salto el método ShouldSerializeValue comprobar el método de la GetValue PropertyDescriptor siempre devuelve True

Solución actual: Como solución que he hecho actualmente las propiedades Enabled y Visible ocultos utilizando el BrowsableAttribute, y creó otras dos propiedades booleanas y se utiliza la DisplayNameAttribute para cambiar su nombre para mostrar para ser Enable y Visible.

Sin embargo, para que esta solución que tengo que escribir estos fragmentos en cada control.

Me estoy perdiendo algo o haciendo mal algo? ¿Por qué la Enabled y propiedad Visible no cambian?

¿Fue útil?

Solución

A continuación encontrará una larga discusión sobre este tema aquí . (Vínculo roto, no puede encontrar uno nuevo)

MSDN página aldo hace que este Observación:

  

La clase InheritedPropertyDescriptor   modifica el valor predeterminado de una   propiedad, por lo que el valor por defecto es   el valor actual en el objeto   instanciación. Esto se debe a la   propiedad se hereda de otra   ejemplo. El distribuidor determina diseñador   restablecer el valor de la propiedad como   estableciéndolo en el valor que se establece   por la clase heredada. Este valor puede   diferir del valor predeterminado almacenado   en los metadatos.

valor de retorno de ShouldSerializeValue se basa en la diferencia entre el valor actual y el valor por defecto, así que creo que esto está directamente relacionado con su problema.

Espero que esto le ayudará a averiguar qué sucede en su propio contexto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top