Mar*_*ina 5 c# wpf propertygrid controls
我正在编写一个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; }
}
}
Run Code Online (Sandbox Code Playgroud)
当我得到一个我需要编辑的对象实例时,我为它创建了一个Wrapper并将其设置为所选对象:
Wrapper wrap = new Wrapper(obj);
propertyGrid.SelectedObject = wrap;
Run Code Online (Sandbox Code Playgroud)
但是我遇到了以下问题 - 只有当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; }
}
}
Run Code Online (Sandbox Code Playgroud)
并做:
Wrapper wrap = new Wrapper(new SomeClass());
propertyGrid.SelectedObject = wrap;
Run Code Online (Sandbox Code Playgroud)
然后一切都运转起来.另一方面,当我执行以下操作时:
int num = 1;
Wrapper wrap = new Wrapper(num);
propertyGrid.SelectedObject = wrap;
Run Code Online (Sandbox Code Playgroud)
然后我可以在网格中看到值"1"(并且它不是灰度)但我无法编辑该值.我注意到如果我将Wrapper的"Value"属性的类型更改为int并删除TypeConverter属性,它就可以工作.我得到了其他原始类型和字符串相同的行为.
问题是什么?
提前致谢!
如果将ExpandableObjectConverter设置为Value属性,则它将不可编辑,这是正常的,因为CanConvertFrom将返回false.如果删除类型转换器,PropertyGrid将使用通用TypeConverter,您再次处于相同的情况.因此,解决方法是附加一个更智能的TypeConverter,它将充当正确的TypeConverter的包装器.这是一个很脏的(我没有太多时间,你将根据需要完成它,因为我刚刚实现了ConvertFrom部分):
public class MySmartExpandableObjectConverter : ExpandableObjectConverter
{
TypeConverter actualConverter = null;
private void InitConverter(ITypeDescriptorContext context)
{
if (actualConverter == null)
{
TypeConverter parentConverter = TypeDescriptor.GetConverter(context.Instance);
PropertyDescriptorCollection coll = parentConverter.GetProperties(context.Instance);
PropertyDescriptor pd = coll[context.PropertyDescriptor.Name];
if (pd.PropertyType == typeof(object))
actualConverter = TypeDescriptor.GetConverter(pd.GetValue(context.Instance));
else
actualConverter = this;
}
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
InitConverter(context);
return actualConverter.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
InitConverter(context); // I guess it is not needed here
return actualConverter.ConvertFrom(context, culture, value);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你需要微调某些东西,请告诉我.
萨科
| 归档时间: |
|
| 查看次数: |
9249 次 |
| 最近记录: |