2011-02-26 43 views
0

我有点困惑。我实现了自己的UserControl,并且希望我的控件在设计时发现在同一个Control中托管的组件(如绑定源)。无法在usercontrol中循环oo组件

代码是这样的:

private void FindComponentByName(string aName) 
{ 
    foreach(Component component in this.Container.components) 
    { 
     if (Component.ToString()==aName) 
     { 
     dosomething(); 
     break; 
     } 
    } 
} 

此代码是不是在设计时要么工作或运行时作为集装箱总是空。

如果我在一个表格中用户控件

private Component FindComponentByName(string aname) 
     { 
      Component result = null; 
      foreach (Component component in this.components.Components) 
      { 
       if (component.ToString() == aname) 
       { 
        result = component; 
        break; 
       } 
      } 
      return result; 
     } 

它的工作原理运行这段代码不是像组件不为空,我设法取回所有组件。

我需要在运行时和设计时做到这一点。

有人能解释我什么是我的错误? 感谢和问候 保罗

回答

1

你的代码应该是这样的:

private void FindComponentByName(string aName) 
{ 
    Control c = FindComponentByName(this); 
    if (c != null) 
    { 
     dosomething(); 
    } 
} 

private Control FindComponentByName(Control c, string aName) 
{ 
    if (c.Name == aName) 
    { 
     return c; 
    } 

    foreach(var control in c.Controls) 
    { 
     //recurse into containers controls to make sure we visit all depths 
     Control found = ctrl.FindComponentByName(control, aName); 
     if (found != null) 
      return found; 
    } 
    return null; 
} 

你甚至可以做,作为一个扩展方法,所以你可以调用的任何控制,你需要它:

public static class MyExtensions 
{ 
    public static Control FindControlWithName(this Control control, string aName) 
    { 
     if (control.Name == aName) 
     { 
      return control; 
     } 
     foreach(var ctrl in control.Controls) 
     { 
      Control found = ctrl.FindControlWithName(aName); 
      if (found != null) 
       return found; 
     } 
     return null; 
    } 
} 

,你可以这样调用它:

if (someControl.FindControlWithName("hola") != null) 
{ 
    dosomething(); 
} 
+0

感谢您的回答,但Controls属性仅返回cvisual控件而不是非视觉控件(组件),例如, BindingSource的。 – 2011-02-26 15:03:51

+0

我的问题在这里解决了:http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/23f714a5-dc38-4632-bb99-116c9d9cfe2f 谢谢大家的帮助 – 2011-03-01 19:44:26

0

你好,我发现这个解决方案可以被几个父类类型使用(我把它作为为UserControl定义的扩展,但可以用于Form或Class)。

public static class UserControlExtension 
{ 
    public static IEnumerable<T> GetAllMembersByType<T>(this UserControl sourceObj, Type requiredType) 
    { 
     var members = sourceObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
     var found = members.Where(fi => fi.FieldType.Equals(requiredType)); 

     List<T> items = new List<T>(); 
     foreach (var fld in found) 
     { 
      T val = (T)fld.GetValue(sourceObj); 
      items.Add(val); 
     } 

     return items; 
    } 

    public static T GetMemberByNameAndType<T>(this UserControl sourceObj, string requiredName, Type requiredType) 
    { 
     var members = sourceObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 
     var found = members.Where(fi => fi.FieldType.Equals(requiredType) && fi.Name == requiredName); 

     if (found.Any()) 
     { 
      var fld = found.FirstOrDefault(); 
      T val = (T)fld.GetValue(sourceObj); 
      return val; 
     } 

     throw new Exception("No member found."); 
    } 


}