c# - 动态选项对话框(使用反射)

标签 c# winforms reflection binding

有谁知道一个好的组件(C# WinForms)可以在给定具有一堆属性的自定义类的情况下创建选项(设置)表单?我并不是在寻找 Shiny 的东西,而是仅仅比属性网格更好的东西。我可以轻松处理视觉部分,但我只是不想浪费时间进行反射来添加和绑定(bind)控件(如果它已经存在)。

我很确定我以前在某处见过类似 Visual Studio 选项的表单,它是动态创建的(一些属性附加到类的属性上,以允许分组和附加信息)。

[编辑] 例如,我可能有一个选项类:

public class Options : SerializableOptions<Options>
{
     [Category("General")]
     [Name("User name")]
     [Description("Some text")]
     public string Username { get; set; }

     [Category("General")]
     [Name("Log in automatically")]
     public bool LogInAutomatically { get; set; }

     [Category("Advanced")]
     // ConnectionType is enum
     public ConnectionType ConnectionType { get; set; }

     // ...
}

将其传递给此表单后,它将创建两个面板(“常规”和“高级”),第一个面板上有一个复选框和一个文本框,第二个面板上有一个组合框(包含所有可用的枚举)。

如果没有这样的控件,你们用什么?为每个选项手动添加、填充、格式化和绑定(bind)控件?

最佳答案

我不知道有任何控件可以让您执行此操作,但您自己执行此操作并不困难。最简单的方法是创建对话框外壳、一个充当选项“面板”基类的用户控件、一个(或多个)控制名称和分组信息的属性以及一个接口(interface)(用户控件实现的) .

每个自定义选项面板都派生自用户控件,并重写某种 Initialize()Save() 方法(由用户控件提供)。它还提供确定名称/分组信息的属性(或多个属性)。

在对话框 shell 中,反射(reflection)性地检查程序集(或所有加载的程序集)中的所有公共(public)类型,查找实现接口(interface)的类型。当您找到类型时,获取属性以确定将其放置在分组中的位置(这里最简单的方法是使用 TreeView ),调用 Activator.CreateInstance 来创建用户控件的实例并将其存储在 Tag 属性中。当用户单击分组中的条目(树节点)时,获取 Tag 并将包含用户控件的面板设置为 Tag 属性中的对象。最后,当用户单击对话框上的“确定”时,循环遍历树节点,获取 Tag 属性并调用 Save 方法。

更新: 另一种选择是使用属性网格控件。它没有“漂亮”的 UI 外观,但功能非常强大,已经支持按类别属性分组,并且具有很大的灵活性。您可以使用显示所有选项的单个属性网格,或者使用具有 TreeView 的“混合”方法,该 TreeView 按主要功能(插件、功能等)(可能基于类型)进行分组。当用户单击该节点时,为属性网格提供对象实例。这种方法的唯一缺点是,当对属性网格值进行更改时,它们是“实时”的,因为基础属性会立即更改,这意味着除了保存每个值的副本之外,不存在“取消”的概念。可以自己更改并执行某种类型的“重置”。

关于c# - 动态选项对话框(使用反射),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1547867/

相关文章:

c# - XElement.Elements().Select() 原因 尝试显式指定类型参数

c# - 比较两个 List<string> 并打印重复项

c# - 用反射检测原生对象

c# - 如何从 Windows 窗体打印明文?

c# - 如何通过反射获取属性的 DisplayAttribute?

.net - BindingFlags 枚举中的 GetField、SetField、GetProperty 和 SetProperty 是什么?

c# - 内存流和文件流的区别

c# - 单元测试应用程序(Windows 通用)中尚不存在 ExpectedException 属性?

winforms - 从其他线程更新UI

c# - 如何从列表框 C# 中删除选定的项目