我有点困惑。我实现了自己的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,我设法检索所有组件。
我需要在运行时和设计时也这样做。
有人可以解释一下我的错误是什么吗? 感谢致敬 保罗
答案 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.");
}
}