Унаследованное управление видимым / включенным значением свойства всегда True: PropertyGrid

StackOverflow https://stackoverflow.com/questions/3934591

Вопрос

Я создал пользовательскую среду хостинга WinForms. Который имеет панель инструментов и свойственную систему.

Управления, отображаемые на панели инструментов, унаследованы от существующих элементов управления 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 сорт.

Метод пишета (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 Собственность не меняется?

Это было полезно?

Решение

Вы найдете долгую дискуссию по этому вопросу здесь. Отказ (Dead Link, не могу найти новый)

Этот MSDN страница Альдо делает это замечание:

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top