本文转自:http://topic.csdn.net/t/20060712/02/4874504.html
通过如下代码在窗体上动态创建了一个控件:
string assName = typeof(System.Windows.Forms.Form).AssemblyQualifiedName;
string assInfo = assemblyQualifiedName.Substring(assemblyQualifiedName.IndexOf( ", "));
Type t = System.Type.GetType( "System.Windows.Forms. " + ctrlType + assInfo, true);
Control ctrl = (Control)Activator.CreateInstance(t);
this.Controls.Add(ctrl);
然后再通过如下代码用字符串重新得到该控件:
Type t = this.GetType();
FieldInfo fieldInfo = t.GetField(ctrlName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags);
但是却发觉fieldInfo是null...何解?那么如何才能根据字符串得到该控件?
你确认ctrlName是当前对象的一个字段么?如果是Controls里的对象,那么你需要获取Controls属性,然后循环在其中找你所需的控件 |
object o=窗体名.GetType().GetField(控件名,System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic).GetValue(窗体名); if(o!=null) { CheckBox dtp=(CheckBox)o; .... |
Control control=this.Controls[控件名] |
to Saucer:如果控件是在Visual Studio中从工具箱拖到Form上,那么我的代码就可以正常运行,现在我是根据一个XML的内容,动态在Form上创建了控件,然后我的代码就运行不成功了。。。 to Knight94:我有一个CreateControls()的函数去读取XML,然后动态在窗体上创建对象,然后等该函数执行完成之后,在另外一个函数里面写“Type t = this.GetType();”这句话的。 |
to stlwj:现在我已经用在Form里面动态创建了一个TextBox:textName,运行 object o=this.GetType().GetField( "textName ",System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic).GetValue(this); 会引发异常:System.NullReferenceException: 未将对象引用设置到对象的实例。 |
是不是因为对象都是动态创建上去的,所以用Type.GetField()无法获取呢? 如果是这样的话,那么我要得到动态创建的对象,应该怎么做呢? 望各位老大指点指点呀! |
创建动态对象: 首先从文件中读取到欲创建对象的名称以及其程序集路径. Assembly asm = Assembly.LoadFile( 程序集文件路径 ); object obj = asm.CreateInstance( "类名称 ",false,BindingFlags.Public|BindingFlags.Instance|BindingFlags.CreateInstance,null,null,null,null );如果该类需要提供构造函数,则需初始化构造函数. |
private void CreateControls(XmlNodeList _xnl, Panel _panel) { foreach(XmlNode _xn in _xnl) { string ctrlType = ((XmlElement)_xn).GetAttribute( "type "); string assName = typeof(System.Windows.Forms.Form).AssemblyQualifiedName; string assInfo = assName .Substring(assemblyQualifiedName.IndexOf( ", ")); Type t = System.Type.GetType( "System.Windows.Forms. " + ctrlType + assemblyInformation, true); Control ctrl = (Control)Activator.CreateInstance(t); _panel.SuspendLayout(); ctrl.Location = new System.Drawing.Point(X, Y); ctrl.Name = _xn[ "Name "].InnerText; ctrl.Size = new System.Drawing.Size(Width], Height); ctrl.Text = _xn[ "Text "].InnerText; ctrl.Visible = bool.Parse(_xn[ "Visible "].InnerText); _panel.Controls.Add(ctrl); _panel.ResumeLayout(); } } private void SetControlsText(XmlNodeList xnl) { foreach(XmlNode _xn in xnl) { Type t = this.GetType(); FieldInfo fieldInfo = t.GetField(_xn[ "Control "].InnerText, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags); ... ... ... } } to Knight94:上面分别是动态创建控件和再用Type.GetField()来获得控件的函数,程序先运行CreateControl()再运行SetControlText(),但fieldInfo最后是null。。。到底是什么原因呢。。。 |
上面的程序有笔误: CreateControl()中的 string assName = typeof(System.Windows.Forms.Form).AssemblyQualifiedName; string assInfo = assName .Substring(assemblyQualifiedName.IndexOf( ", ")); Type t = System.Type.GetType( "System.Windows.Forms. " + ctrlType + assemblyInformation, true); 应该是 string assName = typeof(System.Windows.Forms.Form).AssemblyQualifiedName; string assInfo = assName .Substring(assName.IndexOf( ", ")); Type t = System.Type.GetType( "System.Windows.Forms. " + ctrlType + assInfo, true); |
to 那么如果我在窗体的Load事件里动态创建了一个控件,怎么在余下的代码里操作这个控件呢? 知道名字吗?如果知道可以如下: foreach( Control ctrl in this.Controls ) { if( ctrl.Name == yourName ) { //get it } } |
Sample code as follows: private Control ctrl = null; change Control ctrl = (Control)Activator.CreateInstance(t); with ctrl = (Control)Activator.CreateInstance(t); |
Type t = this.GetType(); --窗体的Type FieldInfo fieldInfo = t.GetField(ctrlName, BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags); -- 这里 GetField 获取的是窗体类的 Field ,而窗体类并不包含名字为ctrlName的成员。 -- 所以这里 获取的值一定是NULL. |