Frage

Ich habe eine benutzerdefinierte WinForms-Hosting-Umgebung erstellt. Welche hat eine Toolbox und Property.

Die Steuerelemente in der Toolbox angezeigt werden aus vorhandenen WinForm Kontrollen geerbt.

Dropdown Quelle:

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
}

Ich habe implementiert ICustomTypeDescriptor zum Ausfiltern von Eigenschaften, die ich will nicht in der PropertyGrid zeigen.

Problem:

Ich bin vor Problem, während Werte von Enabled & Visible Eigenschaften Serialisierung, die von System.Windows.Forms.Control Klasse vererbt werden.

WriteProperties Methode (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;
            }
        }
    }
}

Problem # 1:. Die ShouldSerializeValue Methode zur Enabled & Visible Eigenschaft immer false zurück

Problem # 2:. Auch wenn ich die ShouldSerializeValue Methode, um die GetValue Methode des PropertyDescriptor überspringen überprüfen immer wieder True

Aktuelle Lösung: Zur Umgehung des Problems habe ich zur Zeit die Enabled & Visible Eigenschaften versteckt mit der BrowsableAttribute gemacht, und erstellt zwei andere boolean Eigenschaften und die DisplayNameAttribute verwendet, um ihre Anzeigenamen zu ändern Enable & Visible sein.

Aber für diese Problemumgehung ich diese Schnipsel in jeder Kontrolle zu schreiben.

Bin ich etwas fehlt oder etwas falsch zu machen? Warum sind die Enabled & Visible Eigenschaft nicht ändern?

War es hilfreich?

Lösung

Sie werden eine lange Diskussion über dieses Thema finden hier . (Toter Link kann keine neue finden)

Der MSDN-Seite aldo macht diese Hinweis:

  

Die InheritedPropertyDescriptor Klasse   ändert der Standardwert ein   Eigenschaft, so dass der Standardwert ist   der aktuelle Wert bei Objekt   Instanziierung. Dies liegt daran, die   Eigentum wird von einem anderen geerbten   Beispiel. Der Designer definiert   Zurücksetzen der Eigenschaftswert als   Einstellung auf den Wert, der eingestellt wurde   von der vererbten Klasse. Dieser Wert kann   gespeicherten unterscheiden sich von dem Standardwert   in Metadaten.

ShouldSerializeValue Rückgabewert basiert auf der Differenz zwischen dem aktuellen Wert und dem Standardwert, damit ich denke, das direkt auf Ihr Problem in Zusammenhang steht.

Ich hoffe, dies wird Ihnen helfen, herauszufinden, was in Ihrem eigenen Kontext geschieht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top