解决方案1 - 添加属性
您可以将属性添加到Item
类来获取和设置MyField.Value
:
public string Value
{
get
{
if (MyField != null)
return MyField.Value;
return null;
}
set
{
if (MyField != null)
MyField.Value = value;
}
}
•最好定义一个部分,物业类。
•当您有权访问类的代码时使用此选项。如果这些课程不是你的,请使用第三种解决方案。
解决方案2 - 使用ExpandableObjectConverter
您可以ExpandableObjectConverter
装饰Item
类的MyField
财产。另外随着[Browsable(false)]
装饰FieldType
FieldType
类来隐藏它在属性网格中,如果你想:
[TypeConverter(typeof(ExpandableObjectConverter))]
public FieldType MyField { get; set; }
•要自定义其在MyField
前面显示的文本,可以覆盖的FieldType
ToString
方法并返回Value
。您也可以使用自定义TypeConverter
并覆盖其ConvertTo
方法。
解决方案3 - 使用自定义TypeDescriptor
它并不像第一个解决方案是容易的,但输出完全像你使用的第一个解决方案是什么。它适用于您无法操作这些类的情况。
你可以用这种方式:
var item = new Item() { MyField = new FieldType() { Value = "Some Value" } };
TypeDescriptor.AddProvider(new MyTypeDescriptionProvider(), item);
this.propertyGrid1.SelectedObject = item;
或者通过装饰Item
类:
[TypeDescriptionProvider(typeof(MyTypeDescriptionProvider))]
public class Item
自定义属性描述
public class MyPropertyDescriptor : PropertyDescriptor
{
private PropertyDescriptor subProperty;
private PropertyDescriptor parentProperty;
public MyPropertyDescriptor(PropertyDescriptor parent, PropertyDescriptor sub)
: base(sub, null)
{
subProperty = sub;
parentProperty = parent;
}
public override bool IsReadOnly { get { return subProperty.IsReadOnly; } }
public override void ResetValue(object component)
{
subProperty.ResetValue(parentProperty.GetValue(component));
}
public override bool CanResetValue(object component)
{
return subProperty.CanResetValue(parentProperty.GetValue(component));
}
public override bool ShouldSerializeValue(object component)
{
return subProperty.ShouldSerializeValue(parentProperty.GetValue(component));
}
public override Type ComponentType { get { return parentProperty.ComponentType; } }
public override Type PropertyType { get { return subProperty.PropertyType; } }
public override object GetValue(object component)
{
return subProperty.GetValue(parentProperty.GetValue(component));
}
public override void SetValue(object component, object value)
{
subProperty.SetValue(parentProperty.GetValue(component), value);
OnValueChanged(component, EventArgs.Empty);
}
}
自定义类型说明符
public class MyTypeDescriptor : CustomTypeDescriptor
{
ICustomTypeDescriptor original;
public MyTypeDescriptor(ICustomTypeDescriptor originalDescriptor)
: base(originalDescriptor)
{
original = originalDescriptor;
}
public override PropertyDescriptorCollection GetProperties()
{
return this.GetProperties(new Attribute[] { });
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
var properties = original.GetProperties().Cast<PropertyDescriptor>().ToList();
var parent = properties.Where(x => x.Name == "MyField").First();
var sub = TypeDescriptor.GetProperties(typeof(FieldType))["Value"];
properties.Remove(parent);
properties.Add(new MyPropertyDescriptor(parent, sub));
return new PropertyDescriptorCollection(properties.ToArray());
}
}
定制TypeDescriptorProvider
public class MyTypeDescriptionProvider : TypeDescriptionProvider
{
public MyTypeDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(object))) { }
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType,
object instance)
{
ICustomTypeDescriptor baseDes = base.GetTypeDescriptor(objectType, instance);
return new MyTypeDescriptor(baseDes);
}
}
•使用此选项,如果Item
和FieldType
是不是你的。如果这些类是您的,并且您可以更改其代码,请使用第一种解决方案。
您可以通过创建包装来控制显示内容和显示方式。典型的应用是翻译所有的属性,隐藏一些,运行时切换等。但最基本的答案是使用'[Browsable(false)]'属性。 – Sinatr