在设计时获取当前窗体的所有控件

发布于 2024-11-02 21:19:53 字数 151 浏览 0 评论 0原文

我有一个关于设计时的问题:

我制作了一个具有属性“链接”的组件。 这些链接是控件。现在我想制作一个 UI 对话框(用于在属性网格中编辑此属性)。

如何获取当前窗体的所有控件?我认为该组件与其有联系,但在哪里呢?我找不到任何东西。

谢谢 :)

I have a question about design-time things:

I've made a component with an property "Links".
Those links are Controls. Now I want to make a UI-Dialog (for editing this property in the property grid).

How can I get all controls of the current form? I think the component has an connection to it, but where? I can't find anything.

Thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

丢了幸福的猪 2024-11-09 21:19:53

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

有一个更好的捕鼠器,例如,您会看到它被 HelpProvider 和 ErrorProvider 组件使用。请注意他们如何向窗体上的所有其他控件添加属性。这是通过实现 IExtenderProvider 接口来完成的。 MSDN 库文章 中有一个很好的示例。

This is quite untrivial to do, I don't know of any examples of .NET components that do this. You can get to the form at design time with the Site property but there are problems. What's hard to deal with is the user deleting controls, ones that you have already added to your controls collection. I don't know of any good trigger to keep your collection valid, beyond also having to use a custom designer for the form or user control.

There's a better mousetrap for this, you see it being used by the HelpProvider and ErrorProvider components for example. Note how they add properties to all other controls on the form. This is done by implementing the IExtenderProvider interface. There's an excellent example of this in the MSDN library article.

述情 2024-11-09 21:19:53

您可以获取 <设计时的 code>IDesignerHost 服务。该服务有一个名为 Container 的属性,其中包含 Components。然后,对于每个组件,获取 INestedContainer 服务,然后从该服务获取所有组件。

这就是文档大纲窗口的工作原理。我已更改其方法以使用 List 作为返回值:

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

You can get IDesignerHost service at design-time. This service has a property called Container which has Components. Then for each component, get INestedContainer service and then get all components from that service.

This is how Document Outline window works. I've changed their method to use List<IComponent> as return value:

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

To filter the result to contain just controls, you can call result.TypeOf<Control>().

拥醉 2024-11-09 21:19:53

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

我由于不小心删除了标签控件的文本属性而“丢失”了它。

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

Not sure if this is what you want.

I "lost" a label control by accidentally removing it's text property.

After looking here at this discussion I finally realized that by accessing ANY control property at design time I could use the drop - down at the top of the properties window to locate the control name. Selecting the name revealed the location of the control on the form and exposed it's properties in the properties editor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文