在PropertyGrid中支付和编辑属性的子属性

时间:2016-08-01 12:45:47

标签: c# .net winforms 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; }
}

在我的表单中,我创建了一个Item类的实例。其中包含以下成员:

  • MyField(FieldType的类型)
  • 描述(字符串类型)
  • 容量(一个int)

是否可以仅在Value中显示MyField属性的PropertyGrid成员?

以下是我如何指定PropertyGrid的所选对象属性。

void Form1(object sender, EventArgs e)
{
    propertyGrid1.SelectedObject = new Item();          
}

3 个答案:

答案 0 :(得分:1)

是的,简单:
将计算的只读属性添加到Item

public Item 
{
   public FieldType MyField { get; set; }
   public string MyFieldValue => MyField.Value;
   public string Description { get; set; }
   public int Capacity { get; set; }
}

答案 1 :(得分:0)

我不确定你在寻找什么,但这里有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) 覆盖ToString()的{​​{1}}方法 像这样

FielType

然后将您的public override string ToString() { return Value; } 设置为私有并封装它。将实例作为字符串返回。哪个会使用重写的值。 像这样

MyField

您的MyField将返回重写值private FieldType MyField; public string value{ get{return MyField.ToString();}set;} 的重写值。

答案 2 :(得分:0)

解决方案1 ​​ - 添加属性

您可以向Item课程添加属性以获取和设置MyField.Value

public string Value
{
    get
    {
        if (MyField != null)
            return MyField.Value;
        return null;
    }
    set
    {
        if (MyField != null)
            MyField.Value = value;
    }
}

enter image description here

•最好在部分类中定义该属性 •当您可以访问类的代码时,请使用此选项。如果这些课程不属于您,请使用第3种解决方案。

解决方案2 - 使用ExpandableObjectConverter

您可以使用MyField修饰Item类的ExpandableObjectConverter属性。如果您愿意,还可以使用FieldType[Browsable(false)]装饰FieldType以隐藏它:

[TypeConverter(typeof(ExpandableObjectConverter))]
public FieldType MyField { get; set; }

enter image description here

•要自定义MyField前面显示的文字,您可以覆盖ToString的{​​{1}}方法并返回FieldType。您也可以使用自定义Value并覆盖其TypeConverter方法。

解决方案3 - 使用自定义TypeDescriptor

它不像第一个解决方案那么容易,但输出完全类似于使用第一个解决方案。它适用于无法操纵这些类的情况。

你可以这样使用它:

ConvertTo

或者通过以下方式装饰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);
    }
}

自定义TypeDescriptorProvider

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());
    }
}

•如果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不属于您,请使用此选项。如果这些类是您的,并且您可以更改其代码,请使用第一个解决方案。