【发布时间】:2011-04-23 14:47:44
【问题描述】:
我有一个关于设计时的问题:
我制作了一个带有“链接”属性的组件。 这些链接是控件。现在我想制作一个 UI-Dialog(用于在属性网格中编辑此属性)。
如何获得当前表单的所有控件?我认为组件与它有联系,但在哪里?我什么都找不到。
谢谢:)
【问题讨论】:
标签: c# .net winforms windows-forms-designer design-time
我有一个关于设计时的问题:
我制作了一个带有“链接”属性的组件。 这些链接是控件。现在我想制作一个 UI-Dialog(用于在属性网格中编辑此属性)。
如何获得当前表单的所有控件?我认为组件与它有联系,但在哪里?我什么都找不到。
谢谢:)
【问题讨论】:
标签: c# .net winforms windows-forms-designer design-time
要获取当前表单的所有控件,请使用以下代码获取该表单上所有控件的集合:
MyForm.Controls
编辑:
也许这些会有帮助?
Design-time editor support for controls collection
Adding design-time support for a nested container in a custom/usercontrol (Winforms)
【讨论】:
这很简单,我不知道有任何 .NET 组件的例子可以做到这一点。您可以在设计时使用 Site 属性访问表单,但存在问题。难以处理的是用户删除控件,即您已经添加到控件集合中的控件。除了必须为表单或用户控件使用自定义设计器之外,我不知道有什么好的触发器可以让您的集合保持有效。
有一个更好的捕鼠器,例如 HelpProvider 和 ErrorProvider 组件。请注意它们如何将属性添加到窗体上的所有其他控件。这是通过实现 IExtenderProvider 接口来完成的。 MSDN library article 中有一个很好的例子。
【讨论】:
您可以在设计时获得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>()。
【讨论】:
不确定这是不是你想要的。
我“丢失”了一个标签控件,因为我不小心删除了它的 text 属性。
看了这里的讨论后,我终于意识到,通过在设计时访问任何控件属性,我可以使用属性窗口顶部的下拉菜单来定位控件名称。选择名称会显示控件在表单上的位置,并在属性编辑器中显示它的属性。
【讨论】: