我們知道 C# winform 跨窗體傳值,子父窗體互動一般用委托來實作。之前都是
子窗體
和
父窗體
兩級互動,如果
子窗體
再生一個
子子窗體
,然後
子子窗體
調用
父窗體
函數,這樣該如何操作?我想到的實作方式還是用
委托變量
一級一級的往下傳。下面是實作的效果:

▲ Form1 加載 Uc1,在 Uc1 下加載 Uc2,Uc2 下傳回 Uc1
Form1.cs
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);
}
}
}
UserControl1.cs
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; // 在這綁定
}
}
}
UserControl2.cs
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();
}
}
}
要注意的地方: