在PropertyGrid中显示并编辑属性的子属性
我无法再在Internet中找到我的问题的确切解决方案,因此我正在问这个问题。希望你能帮助我。在PropertyGrid中显示并编辑属性的子属性
我有以下类别:
public Item
{
public FieldType MyField { get; set; }
public string Description { get; set; }
public int Capacity { get; set; }
}
public FieldType
{
public string Value { get; set; }
public string FieldCode { get; set; }
public string TableCode { get; set; }
}
在我的形式,我创建项目类的一个实例。它包含以下成员:
- MyField的(类型的FieldType的)
- 描述(字符串类型)
- 容量(一个int)
是否有可能只显示Value
成员的MyField
物业PropertyGrid
?
以下是我如何分配PropertyGrid
的选定对象属性。
void Form1(object sender, EventArgs e)
{
propertyGrid1.SelectedObject = new Item();
}
是的,很简单:
一个计算的只读属性添加到Item
public Item
{
public FieldType MyField { get; set; }
public string MyFieldValue => MyField.Value;
public string Description { get; set; }
public int Capacity { get; set; }
}
我不是真的知道你正在寻找的,但这里有2个答案
1(如我理解它)
如果你想它只显示Value
当你试图查看一个MyField
实例的属性,那么你所需要做的就是将一个构造函数添加到MyField
所以您可以指定其他两个值和公共属性更改为private
像这样
public FieldType
{
public string Value { get; set; }
private string FieldCode { get; set; }
private string TableCode { get; set; }
}
2.(这将隐藏您的PropertyGrid中的MyField
)
覆盖的FielType
的ToString()
方法,像这样
public override string ToString()
{
return Value;
}
然后将您的MyField
设置为私有并封装它。以字符串形式返回实例。这将使用重写的值。 像这样
private FieldType MyField;
public string value{ get{return MyField.ToString();}set;}
您MyField的将返回重写ToString
值返回值。
解决方案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