PropertyGrid 和对象的动态类型
我正在编写一个 GUI 应用程序,我需要在其中启用编辑任意对象的属性(它们的类型仅在运行时已知)。
我决定使用 PropertyGrid 控件来启用此功能。 我创建了以下类:
[TypeConverter(typeof(ExpandableObjectConverter))]
[DefaultPropertyAttribute("Value")]
public class Wrapper
{
public Wrapper(object val)
{
m_Value = val;
}
private object m_Value;
[NotifyParentPropertyAttribute(true)]
[TypeConverter(typeof(ExpandableObjectConverter))]
public object Value
{
get { return m_Value; }
set { m_Value = value; }
}
}
当我获得需要编辑的对象的实例时,我为它创建一个包装器并将其设置为选定的对象:
Wrapper wrap = new Wrapper(obj);
propertyGrid.SelectedObject = wrap;
但我遇到了以下问题 - 上面的内容仅在以下情况下才按预期工作: obj 的类型是某种自定义类型(即我自己定义的类,或内置的复杂类型),但当 obj 是基元时则不是。
例如,如果我定义:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class SomeClass
{
public SomeClass()
{
a = 1;
b = 2;
}
public SomeClass(int a, int b)
{
this.a = a;
this.b = b;
}
private int a;
[NotifyParentPropertyAttribute(true)]
public int A
{
get { return a; }
set { a = value; }
}
private int b;
[NotifyParentPropertyAttribute(true)]
public int B
{
get { return b; }
set { b = value; }
}
}
并执行:
Wrapper wrap = new Wrapper(new SomeClass());
propertyGrid.SelectedObject = wrap;
那么一切都会顺利进行。另一方面,当我执行以下操作时:
int num = 1;
Wrapper wrap = new Wrapper(num);
propertyGrid.SelectedObject = wrap;
然后我可以在网格中看到值“1”(并且它不是灰度的),但我无法编辑该值。我注意到,如果我将 Wrapper 的“Value”属性的类型更改为 int 并删除 TypeConverter 属性,它就会起作用。 对于其他原始类型和字符串,我得到相同的行为。
问题是什么?
提前致谢!
I'm writing a GUI application where I need to enable editing properties of arbitrary objects (their types are only known at run-time).
I've decided to use the PropertyGrid control to enable this functionality.
I created the following class:
[TypeConverter(typeof(ExpandableObjectConverter))]
[DefaultPropertyAttribute("Value")]
public class Wrapper
{
public Wrapper(object val)
{
m_Value = val;
}
private object m_Value;
[NotifyParentPropertyAttribute(true)]
[TypeConverter(typeof(ExpandableObjectConverter))]
public object Value
{
get { return m_Value; }
set { m_Value = value; }
}
}
When I get an instance of an object I need to edit, I create a Wrapper for it and set it as the selected object:
Wrapper wrap = new Wrapper(obj);
propertyGrid.SelectedObject = wrap;
But I've run into the following problem - the above works as expected only when the type of obj is some custom type (i.e a class that I defined by myself, or a built in complex type) but not when obj is a primitive.
For example, if I define:
[TypeConverter(typeof(ExpandableObjectConverter))]
public class SomeClass
{
public SomeClass()
{
a = 1;
b = 2;
}
public SomeClass(int a, int b)
{
this.a = a;
this.b = b;
}
private int a;
[NotifyParentPropertyAttribute(true)]
public int A
{
get { return a; }
set { a = value; }
}
private int b;
[NotifyParentPropertyAttribute(true)]
public int B
{
get { return b; }
set { b = value; }
}
}
And do:
Wrapper wrap = new Wrapper(new SomeClass());
propertyGrid.SelectedObject = wrap;
Then everything works swell. On the other hand, when I perform the following:
int num = 1;
Wrapper wrap = new Wrapper(num);
propertyGrid.SelectedObject = wrap;
Then I can see the value "1" in the grid (and it's not grayscaled) but I can't edit the value. I noticed that if I change Wrapper's "Value" property's type to int and remove the TypeConverter attribute, it works.
I get the same behavior for other primitive types and strings.
What is the problem?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果将 ExpandableObjectConverter 设置为 Value 属性,则它将不可编辑,这是正常的,因为 CanConvertFrom 将返回 false。如果删除类型转换器,PropertyGrid 将使用通用 TypeConverter,并且您将再次遇到相同的情况。因此,解决方法是附加一个更智能的 TypeConverter,它将充当正确 TypeConverter 的包装器。这是一个脏的(我没有太多时间,你将根据需要完成它,因为我刚刚实现了 ConvertFrom 部分):
如果你需要微调某些东西,请告诉我。
尼古拉斯
If you set ExpandableObjectConverter to your Value property, it won't be editable and this is normal because CanConvertFrom will return false. IF you remove the type converter, the PropertyGrid will use the generic TypeConverter and you are again in the same case. So the workaround is to attach a smarter TypeConverter that will act as a wrapper to the correct TypeConverter. Here is a dirty one (I had not much time, you will complete it as needed since I just implemented the ConvertFrom part):
Let me know if you need to finetune something.
Nicolas
从属性“Value”中删除“TypeConverter”,属性网格将从属性中的值的类型中读取“TypConverter”。
Remove the "TypeConverter" from property "Value", the propertygrid will read the the "TypConverter" from typeo of value which is in property.