C# 利用委托 父子窗口数据传递
## 参考链接
WinForm中利用委托和事件实现子窗体传值给父窗体_winform子窗体向父窗体传值-CSDN博客
C#跨窗体传值的几种方法分析(很详细) - xh6300 - 博客园 (cnblogs.com)
## Form1 父窗口
// .Net8 Winform
using static WinFormsApp6.Form2;
namespace WinFormsApp6
{
// Form1 代码
// 说明: 该方法是用委托来传入和接受方法参数, 委托一般定义在子窗口.
// 该方法有四个控件
// textBox1 用于传送值给Form2.textBox1,
// textBox2 用于接受Form2.textBox2的值.
// button1 传送textBox1 值给Form2.textBox1,
// button2 打开Form2窗口, 并接受来自Form2.Sender_ToForm1的方法参数值
public partial class Form1 : Form
{
Form2 form2; // 实例化窗口2(Form2), 用于调用Form2的方法;
Form2.Weituo? weituo; // 定义一个委托变量weituo, 这个变量用于传送主窗口内一个带参数的方法. 这个委托是来自子窗口(Form2)的委托;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) // 载入窗口执行的任务
{
button1.Enabled = false;
}
void Accept_Form2(string xx) // 接受窗口2 传入到窗口1
{
textBox2.Text = xx; // xx变量接收来自Form2内的委托
}
void sync_Form2(string xx) // 用于同步Form2.textBox3
{
textBox3.Text = xx; // xx变量接收来自Form2内的委托
}
void Sender_ToForm2(string xx) // 将参数传入到窗口2
{
form2.Accept_Form1(xx); // 读取Form2的方法, xx参数等于Form2的方法参数, 类似于Accept_Form2
}
private void button1_Click(object sender, EventArgs e) // 实例化委托并传入值到Form2
{
weituo = new(Sender_ToForm2); // weituo并没有实例化, 实例化委托后并填入执行
// Weituo weituo = new(Sender_ToForm2) // 如果不在类中新建委托变量, 也可以直接在方法内实例化委托 ;
weituo(textBox1.Text); // 执行委托; 用textBox1.Text的值给到Sender_ToForm2的参数, 然后执行Sender_ToForm2. 相当于 Sender_ToForm2(textBox1.Text)
}
private void button2_Click(object sender, EventArgs e) // 实例化Form2的weituo2委托.
{
form2 = new(); // 当该作用域结束, 则实例化对象也被销毁.
button1.Enabled = true; // Sender_ToForm2方法调用了form2, 但是form2没有被实例化, 所以需要先禁用, 待实例化后再启用
form2.weituo2 = new(Accept_Form2); // 实例化Form2的weituo2委托, weituo2 是在 Form2 的Weituo变量.
form2.weituo3 = new(sync_Form2);
form2.Show(); // 显示Form2窗口. 不要使用ShowDialog(), 这样Form1无法使用.
}
private void textBox3_TextChanged(object sender, EventArgs e) // 编辑框被编辑事件.
{
form2.sync_TextBox(textBox3.Text); // 找到Form2的方法
}
// 至此Form1 的代码写完.
// 你需要定义两个带参数的方法, 一个用于接受参数值, 一个用于传送参数值,
// 实例化两个委托, 也是一个用于接受参数值, 一个用于传送参数值.
}
}
## Form2 子窗口
// .Net8 Winform
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.DataFormats;
namespace WinFormsApp6
{
// Form2 代码
// 该方法有三个控件
// textBox1.Text 用于接受来自Form1.textBox1.Text的值
// textBox2.Text 传送到 Form1.textBox2.Text 值
// button1 发送 Form2.textBox2.Text值到Form1.textBox2.Text
public partial class Form2 : Form
{
public delegate void Weituo(string x); // 定义一个带参数的委托, 这个参数是用于传值的
public Weituo? weituo2; // 新建一个公开的委托变量, 这个委托变量是给到Form1来传参的.
public Weituo? weituo3;
public Form2()
{
InitializeComponent();
}
public void Accept_Form1(string x) // 该方法用于给到Form1的方法调用, 所以需要设置为公开.
{
textBox1.Text = x; // 该方法的参数值 x 是来自Form1的 Sender_ToForm2方法参数值
}
public string sync_TextBox(string x) // 该方法用于给到Form1的方法调用, 所以需要设置为公开.
{
return textBox3.Text =x; // 该方法的参数值 x 是来自Form1的 Sender_ToForm2方法参数值
}
private void button1_Click(object sender, EventArgs e) //
{
if (weituo2 != null) // 判断weituo2是否实例化.
{
weituo2(textBox2.Text); // 将textBox2.Text的值给到weituo2内的方法.
}
}
private void textBox3_TextChanged(object sender, EventArgs e) // 编辑框被编辑事件. 如果需要访问Form1的控件属性值还是需要利用委托.
{
if (weituo3 != null) // 判断weituo2是否实例化.
{
weituo3(textBox3.Text); // 将textBox2.Text的值给到weituo2内的方法.
}
}
private void Form2_FormClosed(object sender, FormClosedEventArgs e) // 窗口关闭结束资源
{
this.Dispose();
}
}
// Form2 需要定义一个委托, 不需要在Form2内实例化委托, 因为在Form1.button2中已经实例化委托, 然后再新建一个方法来传参.
// 虽然可以在Form2实例化委托, 但是委托无法调用Form1的方法(就算能够调用也是静态方法, 而控件不是静态类型, 这样会有冲突),
// 如果在Form2中实例化Form1, 相当于Form2的子窗口 如: Form1.Form2.Form1, 这样原来Form1窗口是不会接受参数值的.
//
// 总结下来, 委托是在子窗口定义的, 需要实例化委托两次, 一次用于传参, 一次用于接受参数(应该是Form2的传参),
// 共建立三个带参数的方法用于委托传参, 梳理一下
// 符号说明 < : 接受参数, > : 传送参数.
// Form1.Accept_Form2 < Form2.button1
// Form1.Sender_ToForm2(btton1) > From2.Accept_Form1
//
// 定义流程
// 1. 先在Form2 定义一个带参数委托, 然后在Form2类中 在新建一个委托变量
// 2. 回到Form1 中定义两个带参数的方法, 一个用于传送参数值, 一个用于接受参数值.
// 3. 然后在Form1 在执行方法中实例化委托, 实例化委托需要填入参数. 因为有两个方法所以也需要实例化两个委托处理两个方法.
// 需要注意的是在Form2中不能实例化Form1, 因为无法调用Form1的方法, 所以之前在Form2 新建的委托变量, 就是用在Form1执行方法中调用,
// 执行方法填入Form2.Show(), 实例化的委托和Show方法都包含在该执行方法中, 这样就不需要在Form2中实例化Form1了.
// 4. Form1需要传入参数值到Form2中, 但是不能直接调用Form2的控件, 所以需要新建一个公开的方法来接受Form1方法的参数值.
// 5. 由于Form2窗口是Form1执行方法调用的, 所以还是属于Form1执行方法的作用域内, 在Form1的执行方法中实例化委托, 并且绑定了方法,
// 所以直接在Form2的执行方法中直接调用已被实例化的委托变量即可, 调用该委托变量还需要填入参数值. 在委托被实例化的时候就需要绑定方法.
// 至此就完成了, 需要加强理解委托和方法作用域.
}
## 执行过程
文章编写or整理的内容由作者完成,引用or参考会给出原文链接。