Унаследованный элемент управления Видимое / Включенное свойство Значение Всегда True: PropertyGrid - PullRequest
3 голосов
/ 14 октября 2010

Я создал собственную среду размещения WinForms.Имеет набор инструментов и PropertyGrid.

Элементы управления, отображаемые на панели инструментов, наследуются от существующих элементов управления WinForm.

DropDownList Источник:

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
}

Я реализовал ICustomTypeDescriptor отфильтровать свойства, которые я не хочу показывать в PropertyGrid.

Проблема:

У меня возникла проблема при сериализации значений Enabled &Visible свойства, унаследованные от System.Windows.Forms.Control class.

Метод WriteProperties (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;
            }
        }
    }
}

Задача № 1: Метод ShouldSerializeValue для свойства Enabled & Visible всегда возвращает false.

Задача № 2: Даже если я пропускаю метод ShouldSerializeValue, проверьте GetValue метод PropertyDescriptor всегда возвращает True.

Текущий обходной путь: В качестве обходного пути в настоящее время я создал свойства Enabled & Visible, скрытые с использованием BrowsableAttributeи создал два других логических свойства и использовал DisplayNameAttribute, чтобы изменить отображаемое имя на Enable & Visible.

Но для этого обходного пути я должен написать эти фрагменты в каждом элементе управления.

Я что-то упускаю или делаю что-то не так?Почему свойство Enabled & Visible не изменяется?

1 Ответ

1 голос
/ 23 октября 2010

Вы найдете долгое обсуждение этой проблемы здесь .(неработающая ссылка, не могу найти новую)

Эта страница MSDN aldo делает следующее замечание:

Класс InheritedPropertyDescriptor изменяет значение по умолчанию длясвойство, так что значением по умолчанию является текущее значение при создании объекта.Это потому, что свойство наследуется от другого экземпляра.Дизайнер определяет сброс значения свойства, устанавливая для него значение, которое было установлено унаследованным классом.Это значение может отличаться от значения по умолчанию, хранящегося в метаданных.

Возвращаемое значение ShouldSerializeValue основано на разнице между текущим значением и значением по умолчанию, поэтому я думаю, что это напрямую связано с вашей проблемой.*

Надеюсь, это поможет вам понять, что происходит в вашем собственном контексте.

...