总结C#中窗体间传递数据的几种方法 (由别人的方法整理)

在编写 C#windows 应用程序的时候咱们常常会遇到这种问题,怎么样在两个窗体间传递数据呢? 如下是我整理的网上的各类方法,在遇到一个实际问题:在 form1 中打开一个 form2 窗口做为录入界面,将录入的值经转换后在 form1 中显示。 采用了委托的方法,能够实现。(与 VC 的回调的应用类似)

1.能够经过委托的方法来解决 windows

问题:经过form1作一个录入界面,将里边经过文本框录入的数值复值给 form2中的listview各列,用3textbox1.text举例吧,分别对应listview3个列。 安全

能够这么作,若是两个窗体是在同一个命名空间下 框架

定义一个代理,注意这个代理是全局的:即同一命名空间下,与Form1Form2平级的) ide

public delegate void MyInvoke(string Item1,string Item2,string Item3); 函数

//在窗体From2中有这么一个回调函数,用于在ListView里添加一个新项的: this

private void UpdateListView(string Item1,string Item2,string Item3) spa

{ .net

    ListView1.Items.Add(Item1); 设计

    ListView1.Items[ListView1.Items.Count - 1].SubItems.Add(Item2); 代理

    ListView1.Items[ListView1.Items.Count - 1].SubItems.Add(Item3);

}

//好比说点击Form2的一个按钮弹出Form1进行录入,在点击按钮的事件下:

//把委托传过去

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView));

frmEdit.ShowDialog(this);

//Form1里定义一个属性

private MyInvoke mi=null;

在构造函数中接收这个委托:

public Form1(MyInvoke myInvoke)

{

   this.mi=myInvoke;

}

//录入数据后,点击OK按钮,在点击事件下:

//回调

this.mi(this.TextBox1.Text,this.TextBox3.Text,this.TextBox3.Text);

this.Close();//关闭Form1

补充:若是我要是想再把form2的值给form1

Form1 frmEdit=new Form1(new MyInvoke(UpdateListView),string para1,string para2...);

frmEdit.ShowDialog(this);

而后将Form1的构造函数改为能够接收几个参数的就好了。

2.假如主框架为Form1,打开的搜索对话框是Form2.直接在Form2类中申明一个Form1实例:Form1 f1=new Form1();而后就能够经过f1来调用Form1中的域和函数了。其实不是这样的,你申明的新的Form1实例不是原来的那个Form1对象了,这样操做的是新的Form1中的域和函数,和最早打开的Form1是没有关系的。

咱们要作的是把当前的Form1实例传递给Form2,若是是这样的话,问题就很好解决了。

方法1:首先,咱们在Form2中定义:

private Form1 mF_Form

咱们更改Form2的构造函数为有参数的

public Form2 ( Form1 myForm )
{
//
// Windows
窗体设计器支持所必需的
//
InitializeComponent ( ) ;
this.mF_Form  = myForm ;   /////这样在Form1中申明Form2的时候就把Form1的实例传递过来了
//
// TODO:
InitializeComponent 调用后添加任何构造函数代码
//
}

Form1中,我在 要用到Form2的地方申明以下:

Form2 f2=new  Form2(this);////这里的this指的就是Form1当前的实例,也就是把当前Form1的实例经过Form2的构造函数传递给Form2类(其实在网上看到过比较蠢的方式,就是在构造函数里面传递要传递的信息如:字符串或是数字等,这样作颇有局限性,不能传递其余的,全部咱们能够直接传递实例,来完成传递更多的信息。)

这样在Form2中使用myForm 就能够对原来的Form1窗口进行操做了。可是你要把要操做的Form1中的域和函数定义成public形式的(这样可能不安全),此时的myForm就是真正的最开始打开的Form1了,你能够用这个实例来进行两个窗体的通信了。 ()

3.其实C#中提供了窗体间进行通信的现成的属性,呵呵,咱们能想到的,微软也想到了,他们创造的语言其实确实能够说是人性化了。

Form1类中申明Form2时用以下代码:

Form2 f2=new Form2();//////Form2中的构造函数不改,仍是无参的

f2.owner=this;////这里的this指的是类Form1当前的实例。

//也能够使用函数的方法,给当前实例添加一个附属窗口  代码:this.AddOwnedForm(f2);

Form2类的定义中写以下代码:

Form1 f1=this.owner;

这样f1对应的就是原来的Form1的实例了,也就能够用这个进行通信了。可是仍是要把不一样类之间访问的域和函数定义成public,哎,安全确实是一个问题!!

  4.使用静态类
    这个也是咱们常常要用到的一种数据交互方法。

下面是定义的一个类:

using System;

using System.Collections;

namespace ZZ

{

     public class AppDatas

     {

         private static ArrayList listData;

         static AppDatas()

         {

              listData = new ArrayList();

              listData.Add("DotNet");

              listData.Add("C#");

              listData.Add("Asp.net");

              listData.Add("WebService");

              listData.Add("XML");

         }

         public static ArrayList ListData

         {

              get{return listData;}

         }

         public static ArrayList GetListData()

         {

              return listData;

         }

     }

}

上面包含了一个静态类成员,listData,一个静态构造函数static AppDatas(),用来初始化listData的数据。还有一个静态属性ListData和一个静态GetListData()方法,他们实现了一样的功能就是返回listData

因为前面两篇文章已经讲了不少,这里不细说了,下面是完整的代码:

Form1.cs文件

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

namespace ZZ

{

     public class Form1 : System.Windows.Forms.Form

     {

         private System.Windows.Forms.Button buttonEdit;

         private System.Windows.Forms.ListBox listBoxFrm1;

         private System.ComponentModel.Container components = null;

         public Form1()

         {

              InitializeComponent();

              this.listBoxFrm1.DataSource = AppDatas.ListData;

             

         }

         protected override void Dispose( bool disposing )

         {

              if( disposing )

                   if(components != null)

                       components.Dispose();

              base.Dispose( disposing );

         }

         [STAThread]

         static void Main()

         {

              Application.Run(new Form1());

         }

         private void InitializeComponent()

         {

              this.buttonEdit = new System.Windows.Forms.Button();

              this.listBoxFrm1 = new System.Windows.Forms.ListBox();

              this.SuspendLayout();

              this.buttonEdit.Location = new System.Drawing.Point(128, 108);

              this.buttonEdit.Name = "buttonEdit";

              this.buttonEdit.TabIndex = 1;

              this.buttonEdit.Text = "修改";

              this.buttonEdit.Click += new System.EventHandler(this.buttonEdit_Click);

              this.listBoxFrm1.ItemHeight = 12;

              this.listBoxFrm1.Location = new System.Drawing.Point(12, 8);

              this.listBoxFrm1.Name = "listBoxFrm1";

              this.listBoxFrm1.Size = new System.Drawing.Size(108, 124);

              this.listBoxFrm1.TabIndex = 2;

              this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

              this.ClientSize = new System.Drawing.Size(208, 141);

              this.Controls.Add(this.listBoxFrm1);

              this.Controls.Add(this.buttonEdit);

              this.Name = "Form1";

              this.Text = "Form1";

              this.ResumeLayout(false);

         }

         private void buttonEdit_Click(object sender, System.EventArgs e)

         {

              Form2 formChild = new Form2();

              formChild.ShowDialog();

              this.listBoxFrm1.DataSource = null;

              this.listBoxFrm1.DataSource = AppDatas.ListData;

         }

     }

}

Form2.cs文件

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

namespace ZZ

{

     public class Form2 : System.Windows.Forms.Form

     {

         private System.Windows.Forms.Button buttonOK;

         private System.ComponentModel.Container components = null;

         private System.Windows.Forms.ListBox listBoxFrm2;

         private System.Windows.Forms.Button buttonAdd;

         private System.Windows.Forms.Button buttonDel;

         private System.Windows.Forms.TextBox textBoxAdd;

         public Form2()

         {

              InitializeComponent();

              foreach(object o in AppDatas.ListData)

                   this.listBoxFrm2.Items.Add(o);

         }

         protected override void Dispose( bool disposing )

         {

              if( disposing )

                   if(components != null)

                       components.Dispose();

              base.Dispose( disposing );

         }

         private void InitializeComponent()

         {

              this.buttonOK = new System.Windows.Forms.Button();

              this.listBoxFrm2 = new System.Windows.Forms.ListBox();

              this.buttonAdd = new System.Windows.Forms.Button();

              this.buttonDel = new System.Windows.Forms.Button();

              this.textBoxAdd = new System.Windows.Forms.TextBox();

              this.SuspendLayout();

              this.buttonOK.Location = new System.Drawing.Point(188, 108);

              this.buttonOK.Name = "buttonOK";

              this.buttonOK.TabIndex = 0;

              this.buttonOK.Text = "肯定";

              this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);

              this.listBoxFrm2.ItemHeight = 12;

              this.listBoxFrm2.Location = new System.Drawing.Point(8, 8);

              this.listBoxFrm2.Name = "listBoxFrm2";

              this.listBoxFrm2.Size = new System.Drawing.Size(168, 124);

              this.listBoxFrm2.TabIndex = 2;

              this.buttonAdd.Location = new System.Drawing.Point(188, 44);

              this.buttonAdd.Name = "buttonAdd";

              this.buttonAdd.TabIndex = 3;

              this.buttonAdd.Text = "增长";

              this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);

              this.buttonDel.Location = new System.Drawing.Point(188, 76);

              this.buttonDel.Name = "buttonDel";

              this.buttonDel.TabIndex = 4;

              this.buttonDel.Text = "删除";

              this.buttonDel.Click += new System.EventHandler(this.buttonDel_Click);

              this.textBoxAdd.Location = new System.Drawing.Point(188, 12);

              this.textBoxAdd.Name = "textBoxAdd";

              this.textBoxAdd.Size = new System.Drawing.Size(76, 21);

              this.textBoxAdd.TabIndex = 5;

              this.textBoxAdd.Text = "";

              this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

              this.ClientSize = new System.Drawing.Size(272, 141);

              this.Controls.Add(this.textBoxAdd);

              this.Controls.Add(this.buttonDel);

              this.Controls.Add(this.buttonAdd);

              this.Controls.Add(this.listBoxFrm2);

              this.Controls.Add(this.buttonOK);

              this.Name = "Form2";

              this.Text = "Form2";

              this.ResumeLayout(false);

         }

         private void buttonOK_Click(object sender, System.EventArgs e)
         {
              this.Close();
         }

         private void buttonAdd_Click(object sender, System.EventArgs e)

         {

              if(this.textBoxAdd.Text.Trim().Length>0)

              {

                   AppDatas.ListData.Add(this.textBoxAdd.Text.Trim());

                   this.listBoxFrm2.Items.Add(this.textBoxAdd.Text.Trim());

              }

              else

                   MessageBox.Show("请输入添加的内容!");

             

         }

         private void buttonDel_Click(object sender, System.EventArgs e)

         {

              int index = this.listBoxFrm2.SelectedIndex;

              if(index!=-1)

              {

                    AppDatas.ListData.RemoveAt(index);

                   this.listBoxFrm2.Items.RemoveAt(index);

              }

              else

                   MessageBox.Show("请选择删除项!");

         }

     }

 

     总结,我认为使用静态类比较多的地方就是把应用程序的配置文件装载到一个静态类里面,让全部的窗体和其余实例均可以经过静态属性以及静态方法使用这些数据,好比三层结构或多层结构均可以访问它,而不是在多个实例间传来传去。在这里咱们讨论的是Windows窗体,其实在两个不一样的实例间交互数据,均可以采用三篇文章中的方案实现,除非是这个类特有的属性或着方法。如今都讲完了,虽然不是什么高深的东西,可是但愿能对一些初学者有所帮助,同时也欢迎各位朋友进行技术交流,共同提升。

分析上面几种方法:

1.  采用了委托的方法,能够实现。:很好的实现了数据处理与数据显示的分离,即FORM2(主)显示与FORM1数据处理,(不须要将FORM2的显示放在FORM1中)与VC的回调的应用有延续性。而且确保了FORM1中要修改的属性的私有性。

2.  方法23都是传递主窗口的引用,比较简单易用。能够实现FORM2(主)与FORM1全部数据的传递(不过须要将要FORM1传递和要修改的数据设为PUBLIC),而这样会存在安全问题。

委托方法能够很好地实现数据的保护

相关文章
相关标签/搜索