博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本文转自: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...何解?那么如何才能根据字符串得到该控件?

 

回复于:2006-07-12 03:14:49

你确认ctrlName是当前对象的一个字段么?如果是Controls里的对象,那么你需要获取Controls属性,然后循环在其中找你所需的控件

 

回复于:2006-07-12 09:01:46

object   o=窗体名.GetType().GetField(控件名,System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic).GetValue(窗体名);
if(o!=null)
{
CheckBox   dtp=(CheckBox)o;
....

 

 

回复于:2006-07-12 09:25:21

Control   control=this.Controls[控件名]

 

回复于:2006-07-12 09:47:56

to   Saucer:如果控件是在Visual   Studio中从工具箱拖到Form上,那么我的代码就可以正常运行,现在我是根据一个XML的内容,动态在Form上创建了控件,然后我的代码就运行不成功了。。。

to   Knight94:我有一个CreateControls()的函数去读取XML,然后动态在窗体上创建对象,然后等该函数执行完成之后,在另外一个函数里面写“Type   t   =   this.GetType();”这句话的。

 

回复于:2006-07-12 09:53:47

to   stlwj:现在我已经用在Form里面动态创建了一个TextBox:textName,运行
object   o=this.GetType().GetField( "textName ",System.Reflection.BindingFlags.Instance|System.Reflection.BindingFlags.NonPublic).GetValue(this);

会引发异常:System.NullReferenceException:   未将对象引用设置到对象的实例。

 

回复于:2006-07-12 09:56:26

是不是因为对象都是动态创建上去的,所以用Type.GetField()无法获取呢?

如果是这样的话,那么我要得到动态创建的对象,应该怎么做呢?

望各位老大指点指点呀!

 

回复于:2006-07-12 10:26:18

创建动态对象:
首先从文件中读取到欲创建对象的名称以及其程序集路径.
Assembly   asm   =   Assembly.LoadFile(   程序集文件路径   );

object   obj   =   asm.CreateInstance(   "类名称 ",false,BindingFlags.Public|BindingFlags.Instance|BindingFlags.CreateInstance,null,null,null,null   );如果该类需要提供构造函数,则需初始化构造函数.

 

回复于:2006-07-12 10:29:06

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。。。到底是什么原因呢。。。

 

回复于:2006-07-12 10:33:01

上面的程序有笔误:

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);

 

回复于:2006-07-12 16:30:39

to   那么如果我在窗体的Load事件里动态创建了一个控件,怎么在余下的代码里操作这个控件呢?

知道名字吗?如果知道可以如下:
foreach(   Control   ctrl   in   this.Controls     )
{
          if(   ctrl.Name   ==   yourName   )
          {
                  //get   it  
          }
}

 

回复于:2006-07-12 16:36:29

Sample   code   as   follows:

private   Control   ctrl   =   null;

change
Control   ctrl   =   (Control)Activator.CreateInstance(t);
with
ctrl   =   (Control)Activator.CreateInstance(t);

 

回复于:2006-07-13 10:02:31

Type   t   =   this.GetType();       --窗体的Type

FieldInfo   fieldInfo   =   t.GetField(ctrlName,   BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags);
--   这里   GetField   获取的是窗体类的   Field   ,而窗体类并不包含名字为ctrlName的成员。
--   所以这里   获取的值一定是NULL.