C#WinForm窗体之间的相互操做

  程序员在.Net平台下进行WinForm应用程序开发过程当中,常常会遇到窗体之间的相互传值或者其余的调用操做,这是在.Net平台上编写WinForm程序很重要的一个基础,网络上问及这方面的帖子特别多,我作了简单举例并将具体的方法作了一个总结。
  设计以下的两个窗体:
  From1中button1的功能代码相对简单:
  Form2 Frm2 = new Form2();
  Frm2.Show();
  Form2.textbox1.text=textbox1.text;   
  在输入最后的代码时有问题,系统会提示“窗体调用.Form2”并不包含“textbox1”的定义”,看From2中的定义文件中,有“private System.Windows.Forms.TextBox textBox1;”说明Form2窗体中的textbox1是私有的,对外不能访问,怎么办?改动访问属性,将“Private”改成“internal”(即在本程序集里能够访问)再运行,系统正常了。
   总结:能够经过改变窗体控件的访问属性来进行操做。
 
  系统将窗体控件的访问属性默认为私有,这样作是遵循了面向对象的封装原则,因此,咱们仍是将“internal”改回“Private”,那上面的问题怎么解决?
  既然是打开窗体就传值,那么在From2中声明一个构造函数就而后在From2窗体初始化的时候就传值就能够了,在From2中声明新的构造函数:
  public Form2(string SValue)
  {
            this.textBox1.Text = SValue;
  }
  在From1窗体的button1按钮的点击事件中写以下代码:
  Form2 Frm2 = new Form2(textBox1.Text);
  Frm2.Show();
  代码没有问题,运行时系统报告构造函数错误,原来From2(string SValue)的textbox1对象为空,那么就是说该代码运行于初始化事件以前【在窗体或者控件绘制图形或者其余操做时也会遭遇这样的问题,即在对象初始化以前进行相似操做固然会出现问题】,因此改动代码以下:
  public Form2(string SValue)
  {
            InitializeComponent();//加入初始化事件
            this.textBox1.Text = SValue;
  }
  运行,系统正常了。
   总结:能够定义一个传递对象而且在窗体的构造函数中接收传递对象来处理窗体的传值操做。

 
  如今处理Form1中的button2事件,它的做用是在Form2窗体打开的状况下改变该窗体中的textbox1的值。
  写代码时必须找到打开的窗体而后再赋值,由于对Frm2定义只在button1_Click方法体中存在,因此没法在本方法体中利用Frm2,那么是否是在把Frm2的做用域延伸到整个Form1窗体(在Form1中定义)就能够利用Frm2了。可是这个没有解决问题,关键在于Form2中的textbox1是私有的,因此,咱们没有必要在Form1中定义对Form2的引用。
  找到目前打开的Form2窗体的实例对象,能够应用Application对象,它包含了一个集合对象OpenForms,经过检索它能够找到目前打开的窗体。
  textbox1 既然是私有的,那么咱们能够经过定义属性来操做它,以下:
  public string Textbox1
  {
            get { return textBox1.Text; }
            set { textBox1.Text = value; }
  }
  那么Form1中的button2的点击事件代码能够这样写了:
  ((Form2)Application.OpenForms["Form2"]).Textbox1 =textBox1.Text;
  运行系统,正常。
  问题又来了,当你打开多个Form2实例对象窗体时,上面的代码只改变最早打开的那个,其余的没有反应。
  由于Application.OpenForms["Form2"])是按Form2名称检索【索引器】,检索到后就返回了,因此只有最早打开的Form2对象接收了操做,改动Form1中的button2的点击事件代码以下:
  foreach (Form Frm in Application.OpenForms)
  {
                if (Frm.Text == "Form2")
                {
                    ((Form2)Frm).Textbox1 = textBox1.Text;
                }
  }
  这样就能够对全部打开的Form2对象实例进行相同的操做了。
   总结:根据封装原则,经过属性来封装对象内的字段操做提升安全性,检索Application.OpenForms能够对系统目前打开的窗体进行操做。

 
  窗体传值是一个事件的改变触发另一个方法或者动做,对于此类应用咱们通常经过委托来实现。
  在Form2中写下以下代码:
  public delegate void MyDelegateChange(string Str);//定义委托
  public MyDelegateChange MyChange;//声明
  //定义动做
  private void MyChangeFunction(string Str)
  {
            textBox1.Text = Str;
  }
  在Form2的button2的点击事件中写下以下代码:
  MyChange = new MyDelegateChange(MyChangeFunction);
  在Form1的button2的点击事件中写下以下代码:
   Form2 Frm2 = new Form2();
   foreach (Form Frm in Application.OpenForms)
   {
                if (Frm.Text == "Form2")
                {
                    Frm2 = (Form2)Frm;
                }
   }
   Frm2.MyChange(textBox1.Text);
  运行系统,正常传值。
  咱们还能够经过委托定义事件来处理。
  在Form2中写下入下代码:
  public delegate void MyDelegateChange(string Str);//定义委托
  public event MyDelegateChange OnMyChange;//声明事件
  public void Form2_OnMyChange(string Str)
  {
            //事件动做
            textBox1.Text = Str;
  }
  在Form1的button2的点击事件中写下以下代码:
  Form2 Frm2 = new Form2();
  Frm2.Form2_OnMyChange(textBox1.Text);
  运行,系统正常传值。
  总结:能够经过委托和事件来进行窗体之间的传值操做。

 
  其实,上面是秉承面向对象的原则来处理,看起来麻烦,以下方法能够随意地达到目的:
  Form Frm2 = new Form2();
  foreach (Form Frm in Application.OpenForms)
  {
                if (Frm.Text == "Form2")
                {
                    Frm2 = Frm;
                }
  }
  Frm2.Controls["textbox1"].Text = textBox1.Text;
  在写代码过程当中,经过上面的方式咱们只能操做控件共有的属性和方法,若是是控件特有的,能够经过引用的方式进行处理,假设Form2上面有个CheckBox1的控件,如今在Form1的Button2的点击事件中操做它,能够按以下的方式:
  CheckBox CB1=new CheckBox();
  CB1 = Frm2.Controls["checkBox1"] as CheckBox;
  CB1.Checked = true;
  好比,如今Form2窗体上有个名为button1的按钮,你但愿触发它的点击事件,能够这样写:
  ((Button)Frm2.Controls["button1"]).PerformClick();
  总结:咱们能够经过检索集合对象来进行窗体之间相互灵活的操做。

 
   网络上,对于对话框窗口的传值的问题也不少,解决办法是若是你想获取一个窗口的返回值,直接调用就能够。   固然也能够经过以下方法来调用,好比在Form1中打开了Form2,点击Form2上面的按钮更改Form1上面的textBox1的值,能够以下写:   this.Owner.Controls[“textbox1”].text=”123”;   另外还有一些其余方法,好比:   1、咱们还能够经过API的调用来进行窗体之间的相互操做,只是如今已没有必要这样去作了;   2、设置一个公用类来传参数,通常不可取;   3、设置一个接口来传参数,缺乏灵活性也不可取;
相关文章
相关标签/搜索