nit*_*ter 6 .net propertygrid winforms
为什么SomeClass.ClassField.StructField
财产不会改变propertyGrid
?看来,实例改变后propertyGrid
不会调用.但是相同的代码可以很好地代替.SomeClass.ClassField.set
SomeStruct
Point
SomeStruct
[TypeConverter(typeof(ExpandableObjectConverter))]
public struct SomeStruct
{
private int structField;
public int StructField
{
get
{
return structField;
}
set
{
structField = value;
}
}
public override string ToString()
{
return "StructField: " + StructField;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SomeClass
{
public SomeStruct ClassField
{
get;
set;
}
}
...
var someClass = new SomeClass
{
ClassField = new SomeStruct
{
StructField = 42
}
};
propertyGrid.SelectedObject = someClass;
Run Code Online (Sandbox Code Playgroud)
你需要一个特殊的TypeConverter来覆盖TypeConverter.GetCreateInstanceSupported,因为否则按照值/ copy-boxing魔法发生在场景后面的属性网格处理所有这些的方式.
这是适用于大多数值类型的一个.你声明它是这样的:
[TypeConverter(typeof(ValueTypeTypeConverter<SomeStruct>))]
public struct SomeStruct
{
public int StructField { get; set; }
}
public class ValueTypeTypeConverter<T> : ExpandableObjectConverter where T : struct
{
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null)
throw new ArgumentNullException("propertyValues");
T ret = default(T);
object boxed = ret;
foreach (DictionaryEntry entry in propertyValues)
{
PropertyInfo pi = ret.GetType().GetProperty(entry.Key.ToString());
if (pi != null && pi.CanWrite)
{
pi.SetValue(boxed, Convert.ChangeType(entry.Value, pi.PropertyType), null);
}
}
return (T)boxed;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,它不支持纯字段结构,只支持具有属性的结构,但ExpandableObjectConverter也不支持这些结构,它需要更多代码才能执行此操作.