Question

J'ai créé un environnement d'hébergement WinForms personnalisés. Ce qui a une boîte à outils et un PropertyGrid.

Les commandes affichées dans la boîte à outils sont héritées de contrôles WinForm existants.

DropDownList Source:

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
}

J'ai mis en ICustomTypeDescriptor pour filtrer les propriétés que je ne veux pas montrer dans le PropertyGrid.

Problème:

Je suis face à problème alors que les valeurs sérialisation des propriétés Enabled & Visible qui sont héritées de la classe de System.Windows.Forms.Control.

WriteProperties Méthode (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;
            }
        }
    }
}

Problème n ° 1:. La méthode ShouldSerializeValue pour la propriété Enabled & Visible retourne toujours false

Problème n ° 2:. Même si je saute la méthode ShouldSerializeValue vérifier la méthode GetValue du PropertyDescriptor retourne toujours True

Current Solution: Pour contourner ce problème, je l'ai fait actuellement les propriétés Enabled et Visible cachés en utilisant la BrowsableAttribute, et créé deux autres propriétés booléennes et utilisé le DisplayNameAttribute pour changer leur nom d'affichage pour être Enable & Visible.

Mais pour cette solution de contournement je dois écrire ces extraits dans chaque contrôle.

Suis-je manque quelque chose ou faire du tort quoi que ce soit? Pourquoi la propriété Enabled & Visible ne changent pas?

Était-ce utile?

La solution

Vous trouverez une longue discussion sur cette question ici . (Lien mort, ne peut pas trouver un nouveau)

la page MSDN aldo fait cette remarque:

  

La classe InheritedPropertyDescriptor   modifie la valeur par défaut d'un   la propriété, de sorte que la valeur par défaut est   la valeur actuelle à l'objet   instanciation. En effet, le   propriété est héritée d'un autre   exemple. Le concepteur définit   la réinitialisation de la valeur de la propriété que   la mise à la valeur définie   par la classe héritée. Cette valeur peut   différente de la valeur par défaut stockée   dans les métadonnées.

La valeur de retour de ShouldSerializeValue est basé sur la différence entre la valeur actuelle et la valeur par défaut, donc je pense que cela est directement lié à votre problème.

J'espère que cela vous aidera à comprendre ce qui se passe dans votre propre contexte.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top