【C#】窗体间互相传值

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

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

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

【C#】窗体间互相传值_第1张图片

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

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

【C#】窗体间互相传值_第2张图片

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

【C#】窗体间互相传值_第3张图片

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,同样禁用最大化、最小化按钮之后布局如下:

【C#】窗体间互相传值_第4张图片

具体的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()。

你可能感兴趣的:(C#,容器,窗体,模态框,数值传递)