Visual Studio设计时属性 - 窗体列表下拉菜单

5

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

我有一个公共属性类型为Form的用户控件。
我想在设计时从下拉列表中选择一个窗体。
我希望从一个特定的命名空间UI.Foo.Forms填充窗体下拉列表。

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

我该怎么做呢? 我希望我的表述足够清晰,以免引起混淆。 如果可能的话,我正在寻找一些代码示例。 当我还有其他截止日期要满足时,我正在尝试避免花费太多时间在此上面。

提前感谢您的帮助。

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;
    }
}

我有点知道如何获取表单列表,但我不确定如何在设计视图中,在设计时将其填充到属性网格中,以供公共属性使用。 - Dustin Brooks
更新了我的答案以满足设计时的要求。 - CMerat
1
谢谢Merat,我还需要等待另外14个小时才能接受(去打土耳其猎物了,可能需要几天时间:),但是一切都完美无缺。 - Dustin Brooks

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();
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接