问题
I have a UserControl
that have a few child UserControl
's and those UserControl
's have child UserControl's.
Consider this:
MainUserControl
TabControl
TabItem
UserControl
UserControl
UserControl : ISomeInterface
TabItem
UserControl
UserControl
UserControl : ISomeInterface
TabItem
UserControl
UserControl
UserControl : ISomeInterface
TabItem
UserControl
UserControl
UserControl : ISomeInterface
This is what i have so far, but finds no ISomeInterface
:
PropertyInfo[] properties = MainUserControl.GetType().GetProperties();
foreach (PropertyInfo property in properties)
{
if (typeof(ISomeInterface).IsAssignableFrom(property.PropertyType))
{
property.GetType().InvokeMember("SomeMethod", BindingFlags.InvokeMethod, null, null, null);
}
}
Is it possible so find all the child UserControl
's from MainUserControl
that implement ISomeInterface
via reflection and call a method(void SomeMethod()
) on that interface?
回答1:
You will need to recursively iterate through all the subcontrols within your MainUserControl.
Here's a helper method you can use:
/// <summary>
/// Recursively lists all controls under a specified parent control.
/// Child controls are listed before their parents.
/// </summary>
/// <param name="parent">The control for which all child controls are returned</param>
/// <returns>Returns a sequence of all controls on the control or any of its children.</returns>
public static IEnumerable<Control> AllControls(Control parent)
{
if (parent == null)
{
throw new ArgumentNullException("parent");
}
foreach (Control control in parent.Controls)
{
foreach (Control child in AllControls(control))
{
yield return child;
}
yield return control;
}
}
Then:
foreach (var control in AllControls(MainUserControl))
{
PropertyInfo[] properties = control.GetType().GetProperties();
... Your loop iterating over properties
Or (much better if this will work for you, since it's a lot simpler):
foreach (var control in AllControls(MainUserControl))
{
var someInterface = control as ISomeInterface;
if (someInterface != null)
{
someInterface.SomeMethod();
}
}
Or, using Linq (need a using System.Linq
to do this):
foreach (var control in AllControls(MainUserControl).OfType<ISomeInterface>())
control.SomeMethod();
Which seems best of all. :)
回答2:
Maybe I am looking in the wrong direction myself. What I meant with the comment on Matthews answer was:
foreach (var control in AllControls(MainUserControl))
{
if (control is ISomeInterface)
{
}
}
or
foreach (var control in AllControls(MainUserControl))
{
var someInterface = control as ISomeInterface;
if (someInterface != null)
{
someInterface.SomeMethod();
}
}
来源:https://stackoverflow.com/questions/15741274/how-to-find-all-objects-that-implement-a-interface-and-invoke-a-method