我们知道 C# 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; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); this.userControl1.LoadUserF2 = this.LoadFrm; this.userControl1.action = () => this.button1_Click(null, null); } private UserControl1 userControl1 = new UserControl1() { Dock = DockStyle.Fill}; private void button1_Click(object sender, EventArgs e) { this.LoadFrm(this.userControl1); } private void LoadFrm(Control control) { this.panel1.Controls.Clear(); this.panel1.Controls.Add(control); } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); // this.userControl2.backUc1 = this.action; // 放这里,结果都是 null // 这个绑定不能放构造函数。因为构造函数执行的时候 action = null。 // 主窗体先构造好子窗体,然后再给子窗体 action 赋值。 // 所以,绑定要放在子窗体构造完毕之后。 } private UserControl2 userControl2 = new UserControl2() { Dock = DockStyle.Fill }; public Action<Control> LoadUserF2; public Action action; private void button1_Click(object sender, EventArgs e) { this.LoadUserF2?.Invoke(this.userControl2); this.userControl2.backUc1 = this.action; // 在这绑定 } } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class UserControl2 : UserControl { public UserControl2() { InitializeComponent(); } public Action backUc1; private void button1_Click(object sender, EventArgs e) { backUc1?.Invoke(); } } }
要注意的地方:
在 UserControl1.cs
中的注释中说明。这里的委托绑定不能放在构造函数下,因为构造函数执行的时候 action = null
。主窗体先构造好子窗体,然后再给子窗体 action
赋值。所以,这里的绑定要放在子窗体构造完毕之后。