5

[编辑] 明确地说,我知道如何通过反射获取表单列表。我更关心设计时属性网格。

我有一个具有 Form 类型的公共属性的用户控件。
我希望能够在设计时从下拉列表中选择一个表单。
我想从一组命名空间填充表单下拉列表:UI.Foo.Forms

如果您拥有 Control 的公共属性,这将起作用。在设计时,该属性将自动填充表单上所有控件的下拉列表,供您选择。我只想用命名空间中的所有表单填充它。

我该怎么做呢?我希望我足够清楚,所以没有混淆。如果可能的话,我正在寻找一些代码示例。当我有其他截止日期要满足时,我试图避免在这方面花费太多时间。

提前感谢您的帮助。

4

2 回答 2

7

您可以通过反射轻松获取类:

var formNames = this.GetType().Assembly.GetTypes().Where(x => x.Namespace == "UI.Foo.Forms").Select(x => x.Name);

假设您从与表单相同的程序集中的代码中调用它,您将获得“UI.Foo.Forms”命名空间中所有类型的名称。然后,您可以在下拉列表中显示它,并最终通过反射再次实例化用户选择的任何一个:

Activator.CreateInstance(this.GetType("UI.Form.Forms.FormClassName"));

[编辑]为设计时的东西添加代码:

在您的控件上,您可以创建一个 Form 属性,如下所示:

[Browsable(true)]
[Editor(typeof(TestDesignProperty), typeof(UITypeEditor))]
[DefaultValue(null)]
public Type FormType { get; set; }

其中引用了必须定义的 Editor 类型。该代码非常不言自明,只需进行少量调整,您就可以让它准确地产生您想要的东西。

public class TestDesignProperty : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.DropDown;
    }

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));

        ListBox lb = new ListBox();
        foreach(var type in this.GetType().Assembly.GetTypes())
        {
            lb.Items.Add(type);
        }

        if (value != null)
        {
            lb.SelectedItem = value;
        }

        edSvc.DropDownControl(lb);

        value = (Type)lb.SelectedItem;

        return value;
    }
}
于 2010-05-06T01:30:45.823 回答
2

通过单击选择项目时下拉菜单不会关闭,因此这可能很有用:

为列表框分配单击事件处理程序并添加事件处理程序函数

public class TestDesignProperty : UITypeEditor
{

    // ...

    IWindowsFormsEditorService editorService;

    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
        {
            // ...
            editorService = edSvc ; // so can be referenced in the click event handler

            ListBox lb = new ListBox();
            lb.Click += new EventHandler(lb_Click);
            // ... 
        }



    void lb_Click(object sender, EventArgs e)
    {
        editorService.CloseDropDown();
    }

}
于 2013-02-05T02:44:46.247 回答