【问题标题】:How to set DefaultValueAttribute of the PropertyGrid dynamically or at runtime?如何动态或在运行时设置 PropertyGrid 的 DefaultValueAttribute?
【发布时间】:2013-11-03 03:59:36
【问题描述】:

我正在定义一个与PropertyGrid 控件一起使用的自定义类。比如说,其中一个属性是这样定义的:

[CategoryAttribute("Section Name"),
DefaultValueAttribute("Default value"),
DescriptionAttribute("My property description")]
public string MyPropertyName
{
    get { return _MyPropertyName; }
    set { _MyPropertyName = value; }
}

private string _MyPropertyName;

如您所见,DefaultValueAttribute 定义了该属性的默认值。这样的默认值在两种情况下使用:

  1. 如果此属性值从默认值更改 PropertyGrid 控件会以粗体显示,并且

  2. 如果我调用PropertyGridResetSelectedProperty 方法, 它会将默认值应用到选定的单元格。

这个概念很好用,除了DefaultValueAttribute 的一个限制。它只接受一个常数值。所以我很好奇,我可以动态设置它吗,比如说,从构造函数或代码的后面?

编辑:我找到了this code,让我阅读DefaultValueAttribute

AttributeCollection attributes = TypeDescriptor.GetProperties(this)["MyPropertyName"].Attributes;
DefaultValueAttribute myAttribute = (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];
string strDefaultValue = (string)myAttribute.Value;

问题是,你是怎么设置的?

【问题讨论】:

  • DefaultValueAttribute 没有将属性设置为值,它纯粹是提供信息......检查这个stackoverflow.com/questions/705553/…
  • @Mate:好的。那么如何设置默认值呢? ResetSelectedProperty 方法使用的那个。
  • 您不能使用属性来执行此操作,属性适用于类型,而不是对象。您必须改为提供自定义 PropertyDescriptor。覆盖其 CanResetValue、ResetValue 和 ShouldSerializeValue 成员。尽管它们都只是单行代码,但需要大量代码,一个不错的谷歌查询是“.net custom propertydescriptor”。
  • @HansPassant:我不知道。我准备认输。我不知道他们是如何实现的。我已经浪费了一天的时间试图弄清楚。我想我只需添加一个对象属性并编写我自己的 ResetSelectedProperty 方法来使用它......否则没有太多帮助。
  • 如果这能完美运行,那么再也没有人需要编写自己的 GUI 程序了。您只需将代码生成器指向您的类的声明,然后按下 Magic 按钮。并不是说你真的需要你这样做,这项工作很久以前就外包给了一个亚洲国家。

标签: c# .net winforms reflection propertygrid


【解决方案1】:

终于,我得到了答案!我遇到了一堆展示如何实现 ICustomTypeDescriptorPropertyDescriptor (here's one) 的网站,如果你想在你的 10 行类中添加两页代码,这很好。

这是一种更快的方法。我发现了一个提示here。祝福那些真正发表建设性想法的人!

所以答案是在你的类中提供两种方法。一个是private bool ShouldSerializePPP(),另一个是private void ResetPPP(),其中PPP 是您的属性名称。前一种方法将由PropertyGrid 调用以确定属性值是否从默认值更改,而后一种方法将在PropertyGrid 项重置为默认值时调用。

这是我的类在添加这些添加后的外观,这将允许在运行时为属性设置默认值:

[CategoryAttribute("Section Name"),
DescriptionAttribute("My property description")]
public string MyPropertyName
{
    get { return _MyPropertyName; }
    set { _MyPropertyName = value; }
}
private bool ShouldSerializeMyPropertyName()
{
    //RETURN:
    //      = true if the property value should be displayed in bold, or "treated as different from a default one"
    return !(_MyPropertyName == "Default value");
}
private void ResetMyPropertyName()
{
    //This method is called after a call to 'PropertyGrid.ResetSelectedProperty()' method on this property
   _MyPropertyName = "Default value";
}

private string _MyPropertyName;

【讨论】:

  • 谢谢!非常非常有帮助。
  • 如果你将它与实现IXmlSerializable 结合起来,那么后者在你序列化对象时获胜(即属性被序列化)并且ShouldSerializeXXX() 仍然控制值是否在 PropertyGrid 中以粗体呈现,所以两全其美。
  • 我不知道这是否是 devexpress propertygrid 特有的,但我必须公开上述功能才能使其工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多