当前位置: 首页 > news >正文

C#跨窗体传值的几种方法分析(很详细)

创建一个Winform窗体应用程序项目,然后添加一个Form2窗体。

在Form1和Form2中各添加一个textBox和button:

 

单击Form1中的button1,弹出Form2,然后要做的就是在Form1中的textBox1和Form2中的textBox2中传值。

 

为了方便起见,将Form1称作父窗体,将Form2称作子窗体

 

相对来说,将父窗体的值传到子窗体较为容易实现。下面分别进行说明。

一、父窗体传值给子窗体。

 

方法1:通过Form类构造方法的重载传参。

Form1类中代码:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {
15             Form2 f2 = new Form2(textBox1.Text);
16             f2.ShowDialog();
17         }  
18     }
19 }

Form2类中代码:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         public Form2(string str)
14         {        
15             InitializeComponent();
16             textBox2.Text = str;//这句必须放在InitializeComponent();的后面,否则会引起“空引用异常”
17         }
18 
19     }
20 }

 

方法2:通过外部可访问的中间变量传参。

先看一串无法实现目的的代码。

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         public  string str;//public类型的实例字段
14 
15         private void button1_Click(object sender, EventArgs e)
16         {
17             Form2 f2 = new Form2();
18             str = textBox1.Text;//注意,这句不能放在f2.ShowDialog();的后面,否则会先执行textBox2.Text = f1.str;再执行str = textBox1.Text;
19             f2.ShowDialog();
20         }  
21     }
22 }

Form2中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         private void Form2_Load(object sender, EventArgs e)
14         {
15             Form1 f1 = new Form1();
16             textBox2.Text = f1.str;
17         }
18 
19     }
20 }

结果值没有传过来:

这是因为:Form1 f1 = new Form1();相当于新建了一个对象,这个新对象的str初始值是null(只有该对象的button1被click的时候才会改变str的值)。textBox2.Text = f1.str;其实就是将null赋给了textBox2.Text。

调试如图:

 

static变量可以认为是全局变量,static变量被所有对象所共有,也可以被所有对象所改变,将相关代码修改如下即可:

public static string str;//public类型的实例字段


private void Form2_Load(object sender, EventArgs e)
        { 
            textBox2.Text = Form1.str;
        }

 

它有一种变式:

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {
15             Form2 f2 = new Form2();
16             f2.str = textBox1.Text;
17             f2.ShowDialog();
18 
19         }
20     }
21 }

Form2中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         public string str;//这里str是在Form2类中定义的,并且不需要static关键字
14 
15         private void Form2_Load(object sender, EventArgs e)
16         {
17             textBox2.Text = str;
18         }
19 
20     }
21 }

分析: f2.str = textBox1.Text;将textBox1的值赋给f2.str,由于f2.ShowDialog();跳出来的刚好是这个对象,因此这个对象的str值不为空。最终通过textBox2.Text = str;将值传过去了。跟上一个例子的不同之处是:str声明的位置不一样,一个是在Form1类中,一个是在Form2类中。

 

一、子窗体传值给父窗体。

 

方法1:通过Owner设置窗口归属来传值。

① 通过Controls

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {
15             Form2 f2 = new Form2();
16             f2.ShowDialog(this);//这个this必不可少(将窗体显示为具有指定所有者:窗体f2的所有者是Form1类当前的对象)
17         }
18     }
19 }

Form2中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button2_Click(object sender, EventArgs e)
14         {
15             Form1 f1 = (Form1) this.Owner;//将本窗体的拥有者强制设为Form1类的实例f1
16             f1.Controls["textBox1"].Text = textBox2.Text;
17         }
18 
19     }
20 }

 

② 通过在控件所在类中增加改变控件属性的方法

或者通过在Form1中添加一个ChangeText方法也行:

public void ChangeText(string str)
        {
            textBox1.Text = str;
        }

Form2中代码相应改变为:

private void button2_Click(object sender, EventArgs e)
        {
            Form1 f1 = (Form1) this.Owner;//将本窗体的拥有者强制设为Form1类的实例f1
            f1.ChangeText(textBox2.Text);
        }

 

注意:如果不用Owner,仅仅想用下面的代码实现,是没可能的。

//Form1中:
using System;
using System.Windows.Forms;

namespace WindowsForms跨窗体传值大全
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 f2 = new Form2();
            f2.ShowDialog();
        }

        public void ChangeText(string str)
        {
            textBox1.Text = str;
        }
    }
}


//Form2中:
using System;
using System.Windows.Forms;

namespace WindowsForms跨窗体传值大全
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form1 f1 =new Form1();
            f1.ChangeText(textBox2.Text);
        }

    }
}

//这种代码无法实现目的

 

③ 通过将外界不可访问的控件“属性”封装成可以访问的属性。

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {
15             Form2 f2 = new Form2();
16             f2.ShowDialog(this);
17         }
18 
19         public string TextBox1Value
20         {
21             set { textBox1.Text = value; }
22             get { return textBox1.Text; }
23         }
24 
25     }
26 }

Form2中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button2_Click(object sender, EventArgs e)
14         {
15             Form1 f1 =(Form1)this.Owner;
16             f1.TextBox1Value = textBox2.Text;
17         }
18 
19     }
20 }

 

方法2:通过提供外部可访问的属性和DialogResult的状态来传值(这个例子同时实现了父传子、子传父)。

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {          
15             Form2 f2 = new Form2();
16             f2.TextBox2Value = textBox1.Text;//顺便把父窗体的值先传给子窗体
17 
18             //这一行不需要再写f2.ShowDialog();或者f2.Show();,否则f2会弹出来两次
19 
20             if (f2.ShowDialog() == DialogResult.OK)//这样的语句是合法的:DialogResult f = f2.ShowDialog();
21             {
22                 textBox1.Text = f2.TextBox2Value;
23                 //f2.Close();//这一句写或者不写,f2都会关闭
24             }  
25         }    
26     }
27 }

Form2中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form2 : Form
 7     {
 8         public Form2()
 9         {
10             InitializeComponent();
11         }
12 
13         public string TextBox2Value //将外部不可访问的textBox2.Text封装成属性TextBox1Value
14         {
15             set { textBox2.Text = value; }
16             get { return textBox2.Text; }
17         }
18 
19         private void button2_Click(object sender, EventArgs e)
20         {
21             this.DialogResult = DialogResult.OK;//这里的DialogResult是Form2类对象的属性
22         }
23 
24     }
25 }

 

方法3:通过委托事件来传值。(这种方式可以实现不同控件数据实时联动的复杂功能)

Form1中:

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public partial class Form1 : Form
 7     {
 8         public Form1()
 9         {
10             InitializeComponent();
11         }
12 
13         private void button1_Click(object sender, EventArgs e)
14         {
15             Form2 f2 = new Form2();
16             f2.ChangeText += new ChangeTextHandler(Change_Text);//将事件和处理方法绑在一起,这句话必须放在f2.ShowDialog();前面
17             f2.ShowDialog();            
18         }
19 
20        public void Change_Text(string str)
21         {
22             textBox1.Text = str;
23         }  
24     }
25 }

Form2中:

 

 1 using System;
 2 using System.Windows.Forms;
 3 
 4 namespace WindowsForms跨窗体传值大全
 5 {
 6     public delegate void ChangeTextHandler(string str);  //定义委托
 7 
 8     public partial class Form2 : Form
 9     {
10         public Form2()
11         {
12             InitializeComponent();
13         }
14 
15         public event ChangeTextHandler ChangeText;  //定义事件
16 
17         private void button2_Click(object sender, EventArgs e)
18         {
19             if (ChangeText != null)//判断事件是否为空
20             {
21                 ChangeText(textBox2.Text);//执行委托实例  
22                 this.Close();
23             }           
24         }    
25     }
26 }

 可以用.NET提供的Action<>泛型委托和lambda表达式简化上面这个例子:

 1 //Form1中:
 2 using System;
 3 using System.Windows.Forms;
 4 
 5 namespace WindowsForms跨窗体传值大全
 6 {
 7     public partial class Form1 : Form
 8     {
 9         public Form1()
10         {
11             InitializeComponent();
12         }
13 
14         private void button1_Click(object sender, EventArgs e)
15         {
16             Form2 f2 = new Form2();
17             f2.ChangeText = (str) => textBox1.Text = str;//用lambda表达式实现,这句话必须放在f2.ShowDialog();前面
18             f2.ShowDialog();            
19         }
20     }
21 }
22 
23 
24 //Form2中:
25 using System;
26 using System.Windows.Forms;
27 
28 namespace WindowsForms跨窗体传值大全
29 {  
30     public partial class Form2 : Form
31     {
32         public Form2()
33         {
34             InitializeComponent();
35         }
36 
37         public Action<string> ChangeText;//之前的定义委托和定义事件由这一句话代替
38 
39         private void button2_Click(object sender, EventArgs e)
40         {
41             if (ChangeText != null)//判断事件是否为空
42             {
43                 ChangeText(textBox2.Text);//执行委托实例  
44                 this.Close();
45             }           
46         }    
47     }
48 }

 

参考资料:

http://blog.csdn.net/yuekunge/article/details/9171301

http://www.jb51.net/article/63837.htm

http://jingyan.baidu.com/article/84b4f565d03bf360f6da3213.html

转载于:https://www.cnblogs.com/xh6300/p/6063649.html

相关文章:

  • 数据结构:二叉树的链式存储
  • 用正则表示式分析网页
  • iOS AFNetworking 打印从服务器返回的错误提示信息
  • Ubuntu16.04安装网易云音乐
  • OC 图片圆角实现
  • 常用设计模式之适配器
  • 加速度传感器检测物体倾角的原理
  • codeforces 734E(DFS,树的直径(最长路))
  • php-fpm服务启动脚本
  • html关于图片和链接的笔记
  • jQuery 语法
  • 【FFMPEG】FFMPEG介绍
  • [原创软件]Maya语言切换工具
  • 【GoLang】GoLang 错误处理 -- 异常处理思路示例
  • Tower 实战一:MavLink的连接与通信
  • 深入了解以太坊
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • JAVA并发编程--1.基础概念
  • laravel5.5 视图共享数据
  • node和express搭建代理服务器(源码)
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • ucore操作系统实验笔记 - 重新理解中断
  • 初识 beanstalkd
  • 将回调地狱按在地上摩擦的Promise
  • 利用DataURL技术在网页上显示图片
  • 聊聊hikari连接池的leakDetectionThreshold
  • 每天10道Java面试题,跟我走,offer有!
  • 区块链分支循环
  • 如何利用MongoDB打造TOP榜小程序
  • 详解NodeJs流之一
  • 小程序开发中的那些坑
  • 学习JavaScript数据结构与算法 — 树
  • scrapy中间件源码分析及常用中间件大全
  • ​中南建设2022年半年报“韧”字当头,经营性现金流持续为正​
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #NOIP 2014#day.2 T1 无限网络发射器选址
  • #控制台大学课堂点名问题_课堂随机点名
  • (二)学习JVM —— 垃圾回收机制
  • (分布式缓存)Redis持久化
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)计算机毕业设计高校学生选课系统
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (三十五)大数据实战——Superset可视化平台搭建
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (转)Scala的“=”符号简介
  • (转)关于pipe()的详细解析
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .Net Core与存储过程(一)
  • .NET 使用配置文件
  • .NET 中使用 Mutex 进行跨越进程边界的同步