【C#】窗体间互相传值

来源:互联网 发布:淘宝优惠券赚佣金 编辑:程序博客网 时间:2024/06/07 03:51

网上关于C#之间的窗体之间互相传值其实很坑的。主要有修改要被传递数值的窗体的构造函数,然而这种方法,如果你要做打开一个窗体,然后这个窗体输入完东西之后传递回去,根本就是不知道怎么实现。之后还有什么委托delegate事件event大法,这个虽然能够实现,但我表示自己看了老半天都没看懂这个C#神特性。

比如如下的例子,在Form1点击“修改”按钮,将打开Form2,Form2中有一个文本框,输入完东西,无论用户按回车还是点击确认按钮,都会将输入结果反馈到Form1的Label1上,如果用户点右上角的“关闭”按钮,则不反馈。

同时,注意到,无论是Form1点击“修改”按钮,Form2会在Form1的位置出现,Form2确定修改之后,Form1同样会去到Form2的位置。


这个例子主要的核心是显示如果在两个窗体之间传递数值。

解决方案包含的东西如下:


其中Form2.cs是在解决方案中新建的Windows窗体,Intent.cs是新建的一个C#类。


Intent.cs就是本解决方案的核心,仿造Android的在Activity传递数值的思想,搞一个Key-values的字典dict,这个字典,用于存放窗体与窗体之间传递的数值。dict左边的key用string,右边的values用Object,这样就是面对不同的数值传递都可以应付。同时将这个字典dict直接设置成public static,调用不用这么麻烦。

using System;using System.Collections.Generic;using System.Text;namespace FormPassValues{    class Intent    {        public static Dictionary<string, Object> dict = new Dictionary<string, Object>();    }}

之后的Form1,禁用最大化、最小化按钮布局如下:


Form1.cs的代码如下:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace FormPassValues{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();            this.StartPosition = FormStartPosition.CenterScreen;//设置form1的开始位置为屏幕的中央        }        private void button1_Click(object sender, EventArgs e)        {            Form2 form2 = new Form2();//声明要使用form2窗体            //将form1当前的位置压入Intent中的dict            Intent.dict["form1_top"] = this.Top;            Intent.dict["form1_left"] = this.Left;            Intent.dict["form1_label1_text"] = label1.Text;            if (form2.ShowDialog() == DialogResult.OK)            {//这个判断,将会等到form2被关闭之后才执行,如果form2返回一个OK值                this.Top = (int)Intent.dict["form2_top"];//更新form1的位置                this.Left = (int)Intent.dict["form2_left"];                label1.Text = Intent.dict["form2_textbox1_text"] + "";//更新form1的内容            }        }    }}

之后Form2,同样禁用最大化、最小化按钮之后布局如下:


具体的Form2.cs的代码如下,textbox1按下Enter确定输入是仿造《【C#】利用System.IO中的File类中的ReadAllText与WriteAllText输入输出小文件》(点击打开链接)的处理,这里不再赘述了。

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace FormPassValues{    public partial class Form2 : Form    {        public Form2()        {            InitializeComponent();        }        private void Form2_Load(object sender, EventArgs e)        {            //在初始化的时候,取出Intent中的需要属性,更新自己的位置,同时更新textbox1的内容            this.Top = (int)Intent.dict["form1_top"];            this.Left = (int)Intent.dict["form1_left"];            textBox1.Text = Intent.dict["form1_label1_text"] + "";            textBox1.Focus();//设置焦点停留在textBox1中            textBox1.Select();//同时选中textBox1中的所有文本,必须先有焦点,再选中        }        private void button1_Click(object sender, EventArgs e)        {            //关闭form2之间,将要传给form1的值压入Intent中的dict            Intent.dict["form2_top"] = this.Top;            Intent.dict["form2_left"] = this.Left;            Intent.dict["form2_textbox1_text"] = textBox1.Text;            this.DialogResult = DialogResult.OK;//同时设置返回值为OK,不设置的话,默认返回Cancel            this.Close();        }        private void textBox1_KeyDown(object sender, KeyEventArgs e)        {            if (e.KeyCode == Keys.Enter)//一旦用户在输入过程中输入Enter            {                this.button1_Click(sender,e);//则执行button1“确定”按钮点击事件            }          }    }}

纵观上述程序,没用到什么高深的语法与C#中的一些新的特性,都是所有编程语言都存在的容器类,关于C#容器类的操作请看《【C#】利用正则表达式判断输入是否为纯数字、容器类》(点击打开链接),C#的容器还可以直接像python那样操作,譬如Intent.dict["form2_top"] = this.Top;之句,如果dict中没有form2_top这一项,就自动将this.Top这个值压进去,如果存在,就修改为this.Top。你无须理会到底存在不存在这项。

在窗体间互相传值,关键是理解,在form2.ShowDialog();之后,form1的代码是在这里中断、形成一个断点的,知道form2被关闭之后,代码才继续向下执行的。原理是与《【C#】文件选择对话框OpenFileDialog与下列列表ComboBox》(点击打开链接)一模一样的,因此自己定一个公有的Intent全局类就能够解决这个问题。

同时,这里再补充一下form2.ShowDialog();之后form2是个模态对话框,就是form2不关闭,form1不能进行任何操作。

如果单纯地form2.Show(),form2则与form1没有任何关系了,form2也将没有任何返回值,form1的代码也不会中断在form2.Show()。

2 0
原创粉丝点击