.NET WINDOWS 开发中如何查找一个控件,或者列出所有在WINFORM上的控件?

oswica 2004-10-12 03:14:38
.NET WINDOWS 中没有提供一个比较便捷的方法通过控件名称查找控件。(WEB 开发中有一个FINDCONTROL方法可以完成此工作)
.NET WINDOWS 中是用集合在管理控件的(容器),查找界面控件时,必须遍历所有的容器,其中还可能出现容器中包含容器的情况(要递归的遍历)。
而且对于菜单(包括上下文菜单,不能通过容器(controls)访问,是作为控件或窗体的属性存在。

现在想在WINFORM下写一个和WEB开发中的FINDCONTROL相同功能的方法,但是由于存在上面的问题,效率太低,不知道各位有没有处理此类问题好的方法,请赐教!!!
...全文
409 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
oswica 2004-10-15
  • 打赏
  • 举报
回复
谢谢楼上的,这个比较好用,呵呵
googmuu 2004-10-12
  • 打赏
  • 举报
回复
如果需要遍历窗体下的控件

Type objType=frmXXX.GetType();
MemberInfo [] memberInfo= objType.GetMembers (BindingFlags.Instance | BindingFlags.GetField | BindingFlags.Public |BindingFlags.NonPublic);
foreach (MemberInfo mbi in memberInfo)
{
if (mbi.MemberType==System.Reflection.MemberTypes.Field )
{
object obj=mbi.ReflectedType.GetField (mbi.Name );
if ( obj is MenuItem)
//todo ...
}
}
alias88 2004-10-12
  • 打赏
  • 举报
回复
菜单\工具栏按钮\各种菜单中的容器下的控件都是表单的成员
用反射法还可取得属性,字段,方法,事件
alias88 2004-10-12
  • 打赏
  • 举报
回复
用引用法并不是很方便,很多时候我们需要动态发现,这需用到反射,楼主的问题能得到很好地解决
/// <summary>
/// 根据给定的对象和路径,获得其子孙成员
/// </summary>
/// <param name="pTopObject">要获得的成员是此对象的子孙,一般为Form</param>
/// <param name="pObjPath">依此路径获取,例如: TextBox1 或TextBox1.Size</param>
/// <param name="Index">用索引化属性的可选索引值返回</param>
/// <returns>子孙</returns>
public static object GetMember(object pTopObject, string pObjPath,object[] Index)
{
string[] strMember;
string MemberName="";
object obj=null;
Type objType=null;

try
{
strMember=pObjPath.Split ('.');
for (int i=0; i<strMember.Length && strMember[i]!="" ;i++)
{
if (i==0)
{
obj=(object)pTopObject;
objType=pTopObject.GetType ();
}
MemberName=strMember[i];

obj = (object) objType.InvokeMember(MemberName,
BindingFlags.Public | BindingFlags.NonPublic |BindingFlags.IgnoreCase |
BindingFlags.Instance | BindingFlags.Static| BindingFlags.GetField | BindingFlags.GetProperty , null, obj, null);
if (obj!=null) objType=obj.GetType ();
else throw new Exception ("不能根据:" + pObjPath + "获得" + pTopObject.ToString() + "的成员:" + MemberName);
}
return obj;

}
catch ( System.Exception ex ){ throw new Exception ("获取 " + pObjPath + " 的成员:" + MemberName + "时发生错误:\n" + ex.Message ); }

}

这个静态方法用于动态加载\设置对象
用法如:
GetMember(frmMain,"txtName");
GetMember(frmMain,"txtName.Size") ;
GetMember(frmMain,"txtName.Size.Width");
北京的雾霾天 2004-10-12
  • 打赏
  • 举报
回复
这个问题是不太好,要一个个的在Controls里找,但是在VS2005里面好像有一个IndexOfName(Name)这个方法,VS2003就没有这个方法.
sandsboy 2004-10-12
  • 打赏
  • 举报
回复
foreach(Control ctrl in this.Controls)
{
........
}
oswica 2004-10-12
  • 打赏
  • 举报
回复
呵呵,也非常感谢您的帮助!
你提到根据名称注册对象,如果我可以找到名称和这个对象之间的关系,我上面的问题也就解决了,我就可以直接通过这个方法来返回这个对象(控件)了。
我现在采取了一个折中的方法来解决这个问题(只是对我最开始的方法的一点改进,没有实质的解决问题--没有达到:方便,高效),目前只有先这么用了。

这个问题可能要挂一段时间了!
wnlovezxm 2004-10-12
  • 打赏
  • 举报
回复
也许我理解不了你的需求吧,我真的体会不到你这么做的出发点在那里,如果真的有必要这么做,自己写个哈希类,定义两个方法,一个是根据名称(string)注册对象(object类型),一个是根据名称检索对象并返回就可以了!每实例化一个对象就注册进去,就可以用于后期检索了!其他的帮不上什么了,希望你的问题早日解决!顺祝:
快乐!!!
oswica 2004-10-12
  • 打赏
  • 举报
回复
我需要动态的控制窗体上的一些控件的属性(比如可见与否),我在设计窗体的时候是可以根据这个设置的属性一个一个的找到控件,然后在设置属性,但是这样代码就太多,而且维护也不方便,所以才有希望通过控件名称找到控件的想法。如果实现了,其他的窗体上的控件我只要使用此方法,和维护一下设置就可以了,不需要一个一个的写代码控制了,不知道这样说理由充分不?
wnlovezxm 2004-10-12
  • 打赏
  • 举报
回复
为什么一定要通过字符串来找呢,web中用字符传来传去,那是因为在b和s之间传递对象不方便快皆,现在你做win程序了,对象就在那里,不过是引用来引用去,还要那一套做什么啊,你知道“theForm”了,知道他的类型,那就直接Form newForm = theForm;就可以了,难道一定弄个Form newForm = this.FindContrl("theForm");,非得这样写才舒服?
把FindContrl()方法反编译一下你会看到,其实也是声明了一个同类型对象的引用然后赋予id属性的!因为最开始建立的对象在发向客户端以后已经释放了!不知道表达清楚了吗!
oswica 2004-10-12
  • 打赏
  • 举报
回复
那handle是?
我知道可以通过窗体定义的控件变量来访问,但是如果我现在知道这个控件的名称(字符串类型)如何找到这个控件?
如你上面所说的,现在有Form theForm = new Form(……);那我知道“theForm”怎么找到这个FORM?
wnlovezxm 2004-10-12
  • 打赏
  • 举报
回复
Form theForm = new Form(……);
theForm 就是句柄,你也可以叫它引用,呵呵,叫指针也可以,呵呵!
oswica 2004-10-12
  • 打赏
  • 举报
回复
句柄是在程序运行时创建的,在设计的时候怎么获得?
请楼上的解释!
wnlovezxm 2004-10-12
  • 打赏
  • 举报
回复
知道控件的句柄直接用就行了,除非是私有的,呵呵,所以没必要象web一样FINDCONTROL()
要转换思维,毕竟表现的平台不同了!

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧