解決方案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