ClassA
List<ClassB>
属性。List<ClassB>
属性,PropertyGrid会显示(Collection)
和一个带有3个点的按钮,这会打开一个看起来像这样的新窗口(取自another SO post)。
我想自定义左侧的Members:
DisplayName,因此ClassB
我已覆盖ToString()
方法
public class ClassB
{
public string Name { get; set; }
public TimeSpan Value { get; set; }
public override ToString() { return String.Format("{0} ({1})", this.Name, this.Value); }
}
现在出现了问题:
(00:00:00)
。Test (00:00:00)
,但它只显示Test
我认为这是一个特殊的约定,如果一个类有一个属性Name
并且该值不为null或为空,则控件显示此属性而不是名称。
但是,我还没有找到一个验证该文档的文档,而且我不知道如何更改此行为。我该怎么做?
注意:不能更改属性名称。
答案 0 :(得分:2)
不幸的是,CollectionEditor.GetDisplayText Method中的逻辑非常硬编码。它没有记录,但您可以使用工具对其进行反汇编。这是代码:
protected virtual string GetDisplayText(object value)
{
string str;
if (value == null)
return string.Empty;
// use the Name property
PropertyDescriptor defaultProperty = TypeDescriptor.GetProperties(value)["Name"];
if ((defaultProperty != null) && (defaultProperty.PropertyType == typeof(string)))
{
str = (string) defaultProperty.GetValue(value);
if ((str != null) && (str.Length > 0))
{
return str;
}
}
// or use the DefaultPropertyAttribute
defaultProperty = TypeDescriptor.GetDefaultProperty(this.CollectionType);
if ((defaultProperty != null) && (defaultProperty.PropertyType == typeof(string)))
{
str = (string) defaultProperty.GetValue(value);
if ((str != null) && (str.Length > 0))
{
return str;
}
}
// or use the TypeConverter
str = TypeDescriptor.GetConverter(value).ConvertToString(value);
if ((str != null) && (str.Length != 0))
{
return str;
}
// or use the type name
return value.GetType().Name;
}
这段代码非常讨厌,因为它基本上反过来做事情。它应该使用Name属性作为最后的手段,而不是专注于它......
但是由于CollectionEditor类没有被密封,所以希望不会丢失。这是你如何解决它:
1)在持有集合的类上声明EditorAttribute,如下所示:
public class ClassA
{
[Editor(typeof(MyCollectionEditor), typeof(UITypeEditor))]
public List<ClassB> List { get; set; }
}
2)定义你的自定义集合编辑器,像这样;
public class MyCollectionEditor : CollectionEditor // needs a reference to System.Design
{
public MyCollectionEditor(Type type)
: base(type)
{
}
protected override string GetDisplayText(object value)
{
// force ToString() usage, but
// you also could implement some custom logic here
return string.Format("{0}", value);
}
}