gpt4 book ai didi

winforms - Inherited Control Visible/Enabled 属性值 Always True : PropertyGrid

转载 作者:行者123 更新时间:2023-12-02 04:13:23 29 4
gpt4 key购买 nike

我创建了一个自定义 WinForms 托管环境。其中有一个工具箱和一个 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 的属性类(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 隐藏的属性, 并创建了另外两个 bool 属性并使用了 DisplayNameAttribute将其显示名称更改为 Enable & Visible .

但是对于这种解决方法,我必须在每个控件中编写这些片段。

我错过了什么或做错了什么?为什么是 Enabled & Visible属性不改变?

最佳答案

你会发现关于这个问题的讨论很长here . (死链接,找不到新链接)

这个MSDN page aldo 发表了这样的评论:

The InheritedPropertyDescriptor class modifies the default value of a property, so that the default value is the current value at object instantiation. This is because the property is inherited from another instance. The designer defines resetting the property value as setting it to the value that was set by the inherited class. This value may differ from the default value stored in metadata.



ShouldSerializeValue 的返回值是基于当前值和默认值之间的差异,所以我认为这与您的问题直接相关。

我希望这将帮助您弄清楚在您自己的情况下会发生什么。

关于winforms - Inherited Control Visible/Enabled 属性值 Always True : PropertyGrid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3934591/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com