4

私は、カスタムPropertyDescriptorsをPropertyGridで希望どおりに機能させるのにかなり苦労してきました。

前提:

  • Ageプロパティ、、、、およびTypeを含む「Animal」というクラスがあります。LocationName
  • List<Animal>動物が保管されている場所を含む「AnimalGroup」という別のクラスがあります。このリストを含むクラスメンバーはと呼ばれMembersます。
  • プログラムのUIで、PropertyGridフォーム要素は、PropertGridのプロパティに割り当てられているAnimalGroup内の動物を一覧表示しSelectedObjectます。

私が非常に簡単に作業できる3番目の箇条書き(下の画像を参照)。

AnimalGroupのメンバーを表示するPropertyGrid。

AnimalGroupクラスは、クラスメンバーICustomTypeDescriptor内のAnimalsのリスト機能を実現するためのインターフェイスを実装します。Members

残念ながら、上の画像でわかるように、プロパティ値は単にAnimalのToStringメソッドから返された値です。

PropertyGridの各動物のメンバー(年齢、種類、場所、名前)をユーザーが編集できるようにしたいと思います。どうすればこれを達成できますか? ある種のカスタムエディタが必要になると思います。しかし、正直なところ、グーグルはこれについてあまり出てこなかったので、どこから始めればよいのかわかりません。

この点に到達するために私が従ったチュートリアルは次のとおりです。

そして、あなたがそれを必要とするならば、ここに私のコードがあります(.NET4.0を使用して):

Animal.cs

public class Animal
{
    private String _Name;

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    private String _Type;

    public String Type
    {
        get { return _Type; }
        set { _Type = value; }
    }
    private String _Age;

    public String Age
    {
        get { return _Age; }
        set { _Age = value; }
    }
    private String _Location;

    public String Location
    {
        get { return _Location; }
        set { _Location = value; }
    }

    public override string ToString()
    {
        return this.Name + " - " + this.Type;
    }
}

AnimalGroup.cs

public class AnimalGroup : ICustomTypeDescriptor
{
    public List<Animal> Members;

    public AnimalGroup()
    {
        this.Members = new List<Animal>();
    }

    public AttributeCollection GetAttributes()
    {
        return TypeDescriptor.GetAttributes(this, true);
    }

    public string GetClassName()
    {
        return TypeDescriptor.GetClassName(this, true);
    }

    public string GetComponentName()
    {
        return TypeDescriptor.GetComponentName(this, true);
    }

    public TypeConverter GetConverter()
    {
        return TypeDescriptor.GetConverter(this, true);
    }

    public EventDescriptor GetDefaultEvent()
    {
        return TypeDescriptor.GetDefaultEvent(this, true);
    }

    public PropertyDescriptor GetDefaultProperty()
    {
        return null;
    }

    public object GetEditor(Type editorBaseType)
    {
        return TypeDescriptor.GetEditor(this, editorBaseType, true);
    }

    public EventDescriptorCollection GetEvents(Attribute[] attributes)
    {
        return TypeDescriptor.GetEvents(this, attributes, true);
    }

    public EventDescriptorCollection GetEvents()
    {
        return TypeDescriptor.GetEvents(this, true);
    }

    public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
    {
        PropertyDescriptor[] pds = new PropertyDescriptor[this.Members.Count];

        int i = 0;
        foreach (Animal a in this.Members)
        {
            pds[i] = new AnimalPropertyDescriptor(a, attributes);

            i++;
        }


        return new PropertyDescriptorCollection(pds);
    }

    public PropertyDescriptorCollection GetProperties()
    {
        return this.GetProperties(new Attribute[0]);
    }

    public object GetPropertyOwner(PropertyDescriptor pd)
    {
        return this.Members;
    }
}

AnimalPropertyDescriptor.cs

public class AnimalPropertyDescriptor : PropertyDescriptor
{
    private Animal property;

    public AnimalPropertyDescriptor(Animal target, Attribute[] attrs)
        : base(target.Name, attrs)
    {
        this.property = target;
    }

    public override bool CanResetValue(object component)
    {
        return false;
    }

    public override Type ComponentType
    {
        get { return null; }
    }

    public override object GetValue(object component)
    {
        return property;
    }

    public override bool IsReadOnly
    {
        get { return false;  }
    }

    public override Type PropertyType
    {
        get { return this.property.GetType(); }
    }

    public override void ResetValue(object component)
    {
        // Not relevant.
    }

    public override void SetValue(object component, object value)
    {
        this.property = (Animal)value;
    }

    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }
}

参考までに、コードが少しばかげていることを認識しています(名前の付いた動物、動物グループなど)。

4

1 に答える 1

3

コンバーターがないようです。

internal class AnimalConverter : ExpandableObjectConverter {

  public override object ConvertTo(ITypeDescriptorContext context, 
                                   CultureInfo culture, 
                                   object value,
                                   Type destinationType) {

    if (destinationType == typeof(string) && value is Animal) {
      Animal a = (Animal)value;
      return a.ToString();
    }
    return base.ConvertTo(context, culture, value, destinationType);
  }
}

次に、あなたの動物を飾ります:

[TypeConverter(typeof(AnimalConverter))]
public class Animal {...}

このCodeProjectのPropertyGridでのコレクションデータのカスタマイズされた表示が役に立ちました。

于 2012-08-10T14:13:05.660 に答える