为什么 SomeClass.ClassField.StructField 属性不会在的PropertyGrid 改变? 看来,的PropertyGrid 不叫 SomeClass.ClassField.set 在 SomeStruct 的实例已被更改。但是,同样的code可以很好地点而不是 SomeStruct 。
[类型转换器(typeof运算(ExpandableObjectConverter))] 公共结构SomeStruct { 私人诠释structField; 公众诠释StructField { 得到 { 返回structField; } 组 { structField =价值; } } 公共重写字符串的ToString() { 返回StructField:+ StructField; } } [类型转换器(typeof运算(ExpandableObjectConverter))] 公共密封类SomeClass的 { 公共SomeStruct ClassField { 得到; 组; } } ... VAR SomeClass的=新SomeClass的 { ClassField =新SomeStruct { StructField = 42 } }; propertyGrid.SelectedObject = SomeClass的;解决方案
您需要一个特殊的类型转换器,它覆盖的 TypeConverter.GetCreateInstanceSupported ,因为以其他方式复制按值/拳击魔术发生在幕后的属性网格处理这一切的方式。
下面是一个应该适用于大多数值类型。您声明它是这样的:
[类型转换器(typeof运算(ValueTypeTypeConverter< SomeStruct>))] 公共结构SomeStruct { 公众诠释StructField {获得;组; } } 公共类ValueTypeTypeConverter< T> :ExpandableObjectConverter其中T:结构 { 公众覆盖布尔GetCreateInstanceSupported(ITypeDescriptorContext上下文) { 返回true; } 公众覆盖对象的CreateInstance(ITypeDescriptorContext背景下,IDictionary的propertyValues) { 如果(propertyValues == NULL) 抛出新ArgumentNullException(propertyValues); 牛逼RET =默认(T); 反对盒装= RET; 的foreach(在propertyValues的DictionaryEntry项) { 。的PropertyInfo PI = ret.GetType()的getProperty(entry.Key.ToString()); 如果(PI = NULL和放大器;!&安培; pi.CanWrite) { pi.SetValue(盒装,Convert.ChangeType(entry.Value,pi.PropertyType),NULL); } } 返程(T)盒装; } }请注意它不支持纯粹的现场只结构,只有一个与属性,但ExpandableObjectConverter不支持这些或者说,它需要更多的code做到这一点。
Why SomeClass.ClassField.StructField property doesn't change in a propertyGrid? It seems, propertyGrid doesn't call SomeClass.ClassField.set after SomeStruct instance has been changed. But same code works well with Point instead of 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;解决方案
You need a special TypeConverter that overrides TypeConverter.GetCreateInstanceSupported because otherwise copy-by-value/boxing magic happens behind the scene in the way the property grid handles all this.
Here is one that should work for most value types. You declare it like this:
[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; } }Note it doesn't support pure field-only structs, only the one with properties, but the ExpandableObjectConverter doesn't support these either, it would require more code to do it.
更多推荐
在PropertyGrid中修改结构属性
发布评论