我有许多正在使用的自定义类,我将对其进行解释和发布示例。在解释了他们都做了什么之后,我将尝试清楚地描述我的错误发生的条件。
首先,我使用 PropertyGrid 来显示几种不同类型对象的属性。因为 PropertyGrid 的默认绑定不像我想要的那样具有描述性,所以我创建了一些自定义类,我将它们称为“显示”类。这些 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;}
}
字符串属性“名称”在 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。在我的项目中,我有许多不同类型的对象,它们需要相同类型的重叠显示类属性。
上面你可以看到我在最后两个属性上面添加的 Lines
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
这条线解决了我在propertGrid中显示CustomObject的问题(几乎......稍后会详细介绍)。但是,对于我的自定义列表属性,它的工作方式不同。在自定义列表上,它扩展为仅显示计数和容量(列表的实际属性)这是有道理的,但这不是我想要的。我想查看列表中实际包含的对象。
所以这是我的复杂解决方案,最初来自这个问题:
我有两个类用于以属性的形式将对象动态添加到 propertyGrid 绑定列表。第一个(CustomClass)可以在这里下载。它用于动态创建属性。我使用的第二个类(DisplayIEnumerable)是从第一个类派生的,可以在这里找到。
DisplayIEnumerable 类循环遍历列表对象并向自身添加一个属性,其中包含每个对象中包含的信息。传入一个 DisplayClass 以准确定义这些对象属性应如何在 Grid 中表示。
到目前为止,一切都很好!正如这张图片所证明的(图片不是使用提供的类创建的,字符串在我使用的类中的格式不同,删除了格式化代码以帮助您专注于相关代码:
现在经过漫长的介绍,真正的问题。使用上面的技术,我想编写一个可以动态处理我没有为其编写唯一显示类的 CustomObjects 的类。我打算将此代码留给那些使用该应用程序进行测试的人,以便他们可以更有效地进行测试,而不必为我公司的每个 CustomObjects 提供完整的显示类。(有数百个)相反,通过将 propertyGrid 与下面的类绑定,我希望将所有列表属性和具有相应 DisplayClasses 的 CustomObjects 绑定在它们的位置。
这是我已经尝试过并且有错误的课程。我还没有尝试用我的 DisplayIEnumerable 类来实现 Lists 的替换,我想让基本功能首先工作:
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
}
运行时,PropertyGrid 显示为应有的样子:
但是,一旦您单击展开箭头,什么都不会发生,并且箭头会消失:
上面的类有什么问题,而我的 DisplayIEnumerable 类没有问题,导致这种行为差异?
我正在使用这样的 DisplayObject 类(在 DisplayClass 内):
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public DisplayObject EndJoint { get { if (_member.bcEnd != null) { return new DisplayObject(_member.EndJoint); } else return null; } }
提前致谢!如果有人通过这个问题,我会印象深刻。