我有许多自定义类,我将解释并发布示例。在说明它们的功能后,我将尝试清楚地描述出现错误的条件。
首先,我使用PropertyGrid来显示几种不同类型对象的属性。因为PropertyGrid的默认绑定不像我想要的那么描述性,所以我创建了一些自定义类,我将引用它们为“Display”类。这些Display类是通过传入一个对象并创建属性来构造的,这些属性返回漂亮格式化的字符串和描述,用于传递的真实对象的公共属性(在某些情况下还包括方法)。
我将用以下缩写示例代码进行演示:
这是一个我想在我的PropertyGrid中显示的对象示例:
public class Joint
{
public Joint(...)
{...}
//properties
public string Name { get; set;}
public CustomObject CC { get; set;}
public List<CustomObject> Custom List { get; set;}
}
字符串属性“Name”在PropertyGrid中显示正常。 然而,CustomObject和List的显示方式对我来说并不是很用户友好。
因此,我尝试通过编写这个类来解决问题:
public class DisplayJoint
{
private Joint _jnt;
public DisplayJoint(Joint jnt)
{
_jnt = jnt;
}
//properties
public string Name { get { return _jnt.Name; } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayCustomObject CC { get { return new DisplayCustomObject(_jnt.CC); } }
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public List<CustomObject> CustomList { get; set;}
}
如上所示的代码,我为我的Joint类和CustomObject类创建了特殊的DisplayClasses。在我的项目中,有许多不同类型的对象需要相同的重叠显示类属性。
如上所示,您可以看到我添加的行位于最后两个属性之上。
此行解决了我在propertGrid中想要以我想要的方式显示CustomObject的问题(几乎...稍后再说)。但是,对于我的自定义列表属性,它的工作方式并不相同。在自定义列表上,它会展开以仅显示Count和capacity(List的实际属性)。这是有道理的,但这不是我想要的。我想看到列表中包含的实际对象。
这里是我的复杂解决方案,最初来源于这个问题。我有两个类,用于动态添加对象到属性表格绑定列表中作为属性。第一个类(CustomClass)可以在此处下载。它用于动态创建属性。我使用的第二个类(DisplayIEnumerable)从第一个类派生而来,在此处找到。
DisplayIEnumerable类循环遍历列表对象,并向自身添加一个属性,其中包含每个对象的信息。传入DisplayClass以定义如何在网格中表示这些对象属性。
到目前为止,一切都很好!如下图所示(图片不是使用提供的类创建的,字符串在我使用的类中格式不同,已删除格式化代码以帮助你专注于相关代码:
现在在经过了漫长的介绍之后,真正的问题出现了。使用上述技术,我希望编写一个类,以动态地处理我没有为其编写唯一显示类的自定义对象。我打算将这段代码留给那些使用该应用程序进行测试的人,以便他们可以更有效地测试而无需针对我们公司的每个自定义对象都有完整的显示类。(有数百个)相反,通过将 propertyGrid 与以下类绑定,我希望所有具有相应 DisplayClasses 的列表和 CustomObjects 的属性被绑定到它们所在的位置。这是我已经尝试并遇到错误的类。我还没有尝试使用我的 DisplayIEnumerable 类替换列表,我想先让基本功能正常工作:
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
internal class DisplayObject : CustomClass<T>
{
#region Variables
protected T _obj;
#endregion
#region Constructor
public DisplayObject(T obj)
{
if (obj != null)
{
try
{
Type currentType = typeof(T);
foreach (PropertyInfo propertyInfo in currentType.GetProperties())
{
Attribute[] attributes = new Attribute[1];
if (propertyInfo.GetType() is IEnumerable)
attributes[0] = new TypeConverterAttribute(typeof(ExpandableObjectConverter));
else
attributes[0] = null;
this.Add(new CustomProperty(propertyInfo.Name, propertyInfo, propertyInfo.GetType(), false, true, attributes));
}
}
catch
{
MessageBox.Show("Failure!");
}
}
}
#endregion
#region Properties
[Browsable(false)]
public object Item
{
get { return _obj; }
set { _obj = value; }
}
#endregion
}
当运行时,属性网格看起来应该是这样的: 然而,一旦您点击展开箭头,什么也不会发生,箭头就会消失: 上面的类有什么问题,而我的DisplayIEnumerable类没有问题,导致这种行为差异?
我像这样使用DisplayObject类(在DisplayClass中):
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayObject EndJoint { get { if (_member.bcEnd != null) { return new DisplayObject(_member.EndJoint); } else return null; } }
提前感谢!如果有人能回答这个问题,我会非常印象深刻。