上下文
我有一个非常多的小类或结构。这些类的实现细节并不重要,但是对于每个类都会有一些我想要公开的简单内置数据类型属性,以便可以在WinForms控件中对它们进行编辑。但是这些在不同的课程中会完全不同。例如:
class SleepAction : IGameAction
{
public float Duration { get; set; }
}
class TeleportCharacterAction : IGameAction
{
public string CharacterId { get; set;
public string DestinationRoomId { get; set; }
public Vector2 DestinationPosition { get; set; }
}
问题是我想要一个单个 WinForms控件,它能够编辑这些对象类型的所有。顶部会有一个所有类类型的下拉列表,当从此下拉列表中选择一个项目时,界面将更改为适应该类型的属性,以及创建该类型的实例来存储数据。
起初我正在考虑手工制作这些接口,可能使用TabControl
对象,每个类一个选项卡,隐藏选项卡。但随后类的数量呈指数增长,所以我转向其他解决方案,可能使用属性和反射。我只是不确定如何开始。
我现在想到的是:
class ActionEditorControl : UserControl
{
void ChangeEditorMode(Type type)
{
// Clear all GUI interface
// Create object of type Type with default constructor
// Use Type metadata to generate new GUI interface
// Databind new interface to object properties
}
object GetObject()
{
// Return current object
}
}
在我的模型对象上,我可以使用属性来添加必要的元数据:
class SleepAction : IGameAction
{
[FieldLabel("Duration")]
[FieldType("NumericSpinner")]
public float Duration { get; set; }
}
class TeleportCharacterAction : IGameAction
{
[FieldLabel("Character")]
[FieldType("CharacterList")]
public string CharacterId { get; set;
[FieldLabel("Room")]
[FieldType("RoomList")]
public string DestinationRoomId { get; set; }
[FieldLabel("Position")]
[FieldType("VectorPicker")]
public Vector2 DestinationPosition { get; set; }
}
当然,我需要教我控制如何解释这些属性。现在我的实际问题。
具体问题
答案 0 :(得分:2)
是的,这应该有用,我已经构建了类似的东西来生成基于实体的动态搜索对话框。
自定义属性可以标识应该在表单上显示的属性。然后,表单可以为这些属性生成控件,并使用数据绑定将控件链接回对象上的属性。
TableLayoutPanel可以帮助生成控件的布局。一列可以存储标签对象,第二列可以存储控件(文本框等)。如果你想要更多的列,可以使用几组。
使用属性
由于您有类型,因此您可以在每个属性中搜索特殊属性:
foreach (var property in searchObjectType.GetProperties())
{
var labelAttrib = (FieldLabelAttribute)property.GetCustomAttributes(typeof(FieldLabelAttribute), false).FirstOrDefault();
var typeAttrib = (FieldTypeAttribute)property.GetCustomAttributes(typeof(FieldTypeAttribute), false).FirstOrDefault();
}
表格面板:
一旦你知道你需要构建一个控件,弄清楚你要构建什么样的控件:(这假设你有一个带有Order属性的属性,所以你知道'在哪里'将控件放在网格中这个例子基于五个列,分别是标签,控制,间隔,标签,控制):
if (type == typeof(string))
{
generatedControl = new Textbox();
generatedControl.DataBindings.Add("Text", myObject, property.Name);
}
然后将控件添加到表中(假设您创建了一个标签控件):
pnlLayout.Controls.Add(label, (myAttrib.Order % 2 * 3), myAttrib.Order / 2);
pnlLayout.Controls.Add(generatedControl, (myAttrib.Order % 2 * 3) + 1, myAttrib.Order / 2);
答案 1 :(得分:1)
你所描述的内容听起来很像PropertyGrid。