我一直在努力让自定义 PropertyDescriptors 以我想要的方式使用 PropertyGrid。
前提:
- 我有一个名为“Animal”的类,其中包含属性
Age
、Type
、Location
和Name
。 - 我有另一个名为“AnimalGroup”的类,其中包含
List<Animal>
存储动物的位置。包含此列表的类成员称为Members
。 - 在程序的 UI 中,表单元素将列出分配给 PropertGrid属性
PropertyGrid
的 AnimalGroup 中的动物。SelectedObject
第三个子弹我可以很容易地开始工作(见下图)。
AnimalGroup 类实现了该ICustomTypeDescriptor
接口以在其Members
类成员中实现 Animals 的列表功能。
不幸的是,如上图所示,属性值只是 Animal 的 ToString 方法返回的值。
我想让用户能够编辑 PropertyGrid 中每个动物的成员(年龄、类型、位置和名称)。我怎样才能做到这一点? 我认为需要有某种类型的自定义编辑器。然而,老实说,我不知道从哪里开始,因为谷歌搜索并没有出现太多。
以下是我遵循的教程:
如果需要,这是我的代码(使用 .NET 4.0):
动物.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;
}
}
动物组.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;
}
}
仅供参考,我知道代码有点荒谬(有名字的动物,动物群体等)。