无法循环用户控件中的组件

时间:2011-02-26 08:49:56

标签: c# winforms

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

代码是这样的:

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

此代码在设计时或运行时无效,因为Container始终为null。

如果我在不在UserControl中的表单中运行此代码

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

它可以工作,因为组件不是null,我设法检索所有组件。

我需要在运行时和设计时也这样做。

有人可以解释一下我的错误是什么吗? 感谢致敬 保罗

2 个答案:

答案 0 :(得分: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();
}

答案 1 :(得分: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.");
    }


}