问题
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 :)
回答1:
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.
回答2:
To get all of the controls of the current form then use the following code to get a collection of all of the controls on that form:
MyForm.Controls
See this MSDN help
Edit:
Perhaps these will help?
Design-time editor support for controls collection
http://social.msdn.microsoft.com/Forums/en-US/winformsdesigner/thread/64df27e7-8502-42ac-8634-cf8a8937d922/
Adding design-time support for a nested container in a custom/usercontrol (Winforms)
回答3:
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>()
.
回答4:
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.
来源:https://stackoverflow.com/questions/5764841/get-all-controls-of-the-current-form-at-design-time