在设计时获取当前表单的所有控件

时间:2011-04-23 14:47:44

标签: c# .net winforms windows-forms-designer design-time

我对设计时的事情有疑问:

我制作了一个带有“链接”属性的组件。 这些链接是控件。现在我想创建一个UI-Dialog(用于在属性网格中编辑此属性)。

如何获取当前表单的所有控件?我认为该组件与它有连接,但在哪里?我找不到任何东西。

谢谢:)

4 个答案:

答案 0 :(得分:2)

答案 1 :(得分:1)

这是非常重要的,我不知道任何.NET组件的例子。您可以在设计时使用Site属性访问表单,但是存在问题。难以处理的是用户删除控件,即已添加到控件集合中的控件。除了还必须为表单或用户控件使用自定义设计器之外,我不知道保持您的集合有效的任何良好触发器。

有一个更好的捕鼠器,你可以看到HelpProvider和ErrorProvider组件正在使用它。请注意它们如何向表单上的所有其他控件添加属性。这是通过实现IExtenderProvider接口完成的。 MSDN library article中有一个很好的例子。

答案 2 :(得分:0)

您可以在设计时获得IDesignerHost服务。该服务具有一个名为Container的属性,该属性具有Components。然后为每个组件获取INestedContainer服务,然后从该服务获取所有组件。

这是文档大纲窗口的工作方式。我已经更改了他们的方法,以使用List<IComponent>作为返回值:

List<IComponent> GetSelectableComponents(IDesignerHost host)
{
    var components = host.Container.Components;
    var list = new List<IComponent>();
    foreach (IComponent c in components)
        list.Add(c);
    for (var i = 0; i < list.Count; ++i)
    {
        var component1 = list[i];
        if (component1.Site != null)
        {
            var service = (INestedContainer)component1.Site.GetService(
                typeof(INestedContainer));
            if (service != null && service.Components.Count > 0)
            {
                foreach (IComponent component2 in service.Components)
                {
                    if (!list.Contains(component2))
                        list.Add(component2);
                }
            }
        }
    }
    return list;
}

要过滤结果以仅包含控件,可以调用result.TypeOf<Control>()

答案 3 :(得分:-1)

不确定这是否是你想要的。

我通过意外删除标签控件的文本属性来“丢失”标签控件。

在这里讨论后,我终于意识到通过在设计时访问ANY控件属性,我可以使用属性窗口顶部的下拉列表来定位控件名称。选择名称会在窗体上显示控件的位置,并在属性编辑器中显示它的属性。