私は、カスタムPropertyDescriptorsをPropertyGridで希望どおりに機能させるのにかなり苦労してきました。
前提:
Age
プロパティ、、、、およびType
を含む「Animal」というクラスがあります。Location
Name
List<Animal>
動物が保管されている場所を含む「AnimalGroup」という別のクラスがあります。このリストを含むクラスメンバーはと呼ばれMembers
ます。- プログラムのUIで、
PropertyGrid
フォーム要素は、PropertGridのプロパティに割り当てられているAnimalGroup内の動物を一覧表示しSelectedObject
ます。
私が非常に簡単に作業できる3番目の箇条書き(下の画像を参照)。
AnimalGroupクラスは、クラスメンバーICustomTypeDescriptor
内のAnimalsのリスト機能を実現するためのインターフェイスを実装します。Members
残念ながら、上の画像でわかるように、プロパティ値は単にAnimalのToStringメソッドから返された値です。
PropertyGridの各動物のメンバー(年齢、種類、場所、名前)をユーザーが編集できるようにしたいと思います。どうすればこれを達成できますか? ある種のカスタムエディタが必要になると思います。しかし、正直なところ、グーグルはこれについてあまり出てこなかったので、どこから始めればよいのかわかりません。
この点に到達するために私が従ったチュートリアルは次のとおりです。
- 実行時にPropertyGridに(から)アイテムを追加(削除)します
- 辞書オブジェクトで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;
}
}
参考までに、コードが少しばかげていることを認識しています(名前の付いた動物、動物グループなど)。