التحكم الموروثة مرئية/قيمة الخاصية الممكّن دائمًا صحيح: PropertyGrid

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

سؤال

لقد أنشأت بيئة استضافة مخصصة. التي لديها صندوق أدوات و propertyGrid.

يتم توريث عناصر التحكم المعروضة في صندوق الأدوات من عناصر تحكم Winform الموجودة.

مصدر القفل:

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 صف دراسي.

طريقة 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 الملكية دائما تعيد خطأ.

المشكلة رقم 2: حتى لو تخطيت ShouldSerializeValue الطريقة تحقق من GetValue طريقة PropertyDescriptor يعود دائما True.

الحل البديل الحالي:كحل بديل ، قمت حاليًا بعمل Enabled & Visible الخصائص المخفية باستخدام BrowsableAttribute, ، وخلق اثنين من الخصائص المنطقية الأخرى واستخدمت DisplayNameAttribute لتغيير اسم العرض الخاص بهم ليكون Enable & Visible.

لكن بالنسبة لهذا الحل ، يجب أن أكتب هذه المقتطفات في كل عنصر تحكم.

هل أفتقد شيئًا أو أفعل أي شيء خاطئ؟ لماذا Enabled & Visible الممتلكات لا تتغير؟

هل كانت مفيدة؟

المحلول

ستجد مناقشة طويلة حول هذه المسألة هنا. (Dead Link ، لا يمكن العثور على واحدة جديدة)

هذه صفحة MSDN ألدو يدلي هذه الملاحظة:

تعمل فئة ClortedPropertyDescriptor على تعديل القيمة الافتراضية للخاصية ، بحيث تكون القيمة الافتراضية هي القيمة الحالية في إنشاء مثيل للكائن. وذلك لأن الخاصية ورثت من مثيل آخر. يحدد المصمم إعادة تعيين قيمة الخاصية على أنها ضبطها على القيمة التي تم تحديدها بواسطة الفئة الموروثة. قد تختلف هذه القيمة عن القيمة الافتراضية المخزنة في البيانات الوصفية.

تعتمد قيمة إرجاع usserializeValue على الفرق بين القيمة الحالية والقيمة الافتراضية لذلك أعتقد أن هذا مرتبط مباشرة بمشكلتك.

آمل أن يساعدك هذا في معرفة ما يحدث في سياقك الخاص.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top