我一直在努力让自定义PropertyDescriptors按照我想要的方式使用PropertyGrid。
前提:
Age
,Type
,Location
和Name
。List<Animal>
。包含此列表的类成员称为Members
。PropertyGrid
表单元素将列出分配给PropertGrid的SelectedObject
属性的AnimalGroup中的Animals。第三个项目我可以很容易地工作(见下图)。
AnimalGroup类实现ICustomTypeDescriptor
接口,以实现其Members
类成员中动物的列表功能。
不幸的是,正如您在上图中看到的那样,属性值只是Animal的ToString方法返回的值。
我想让用户能够在PropertyGrid(年龄,类型,位置和名称)中编辑每个Animal的成员。我怎样才能实现这个目标?我认为需要某种类型的自定义编辑器。但老实说,我不知道从哪里开始,因为谷歌搜索没有为此做多少。
以下是我遵循的教程:
如果你需要它,这是我的代码(使用.NET 4.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;
}
}
仅供参考,我知道代码有点荒谬(有名字的动物,动物群等)。
答案 0 :(得分: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 {...}
发现此代码项目Customized display of collection data in a PropertyGrid很有帮助。