通过委托可以实现通过B窗口的按钮来控制A窗口的事件,实现不同窗口间的交互,还可以将不同窗口间的数值进行传递,转换。
1.通过委托(delegate)实现通过B窗口的按钮来控制A窗口的事件
如图所示,通过点击该窗口(后面称Other窗口)的“关闭端口”按钮实现与点击主窗口“打开端口”相同的事件。
首先,在Other窗口定义一个 bt_OpenClickEventHandler委托和一个btOpenClick事件 用来在F_Main窗口订阅该事件,然后通过bt_Open1的点击事件触发设置的btOpenClick事件。
那么在Other窗口代码为如下所示:
public partial class Other : Form
{
public Other()
{
InitializeComponent();
}
//定义一个 bt_OpenClickEventHandler委托和一个btOpenClick事件 用来在F_Main窗口订阅该事件
public delegate void bt_OpenClickEventHandler(object sender, EventArgs e);
public event bt_OpenClickEventHandler btOpenClick;
//bt_Open1_Click就是Other窗口点击“关闭端口”的事件
private void bt_Open1_Click(object sender, EventArgs e)
{
if (countOpen == 0)
{
bt_Open.Text = "打开端口";
bt_Open.BackColor = Color.LightGreen;
cm_Port.Enabled = true;
countOpen++;
//触发btOpenClick事件
btOpenClick?.Invoke(this, e);
}
else
{
bt_Open.Text = "关闭端口";
bt_Open.BackColor = Color.SkyBlue;
cm_Port.Enabled = false;
countOpen--;
//触发btOpenClick事件
btOpenClick?.Invoke(this, e);
}
}
}
其次,在主窗口声明Other窗口,然后在初始化位置订阅Other窗口的btOpenClick事件,F_Main窗口代码如下(注:bt_Open_Click事件内变量的定义代码未给出,本代码仅供理解委托的用法):
public partial class F_Main : Form
{
public F_Main()
{
InitializeComponent();
//订阅窗口Other的btOpenClick事件
other.btOpenClick += new Other.bt_OpenClickEventHandler(bt_Open_Click);
//这里的bt_Open_Click就是主窗口的“打开端口”的点击事件。
}
Other other = new Other();
private void bt_Open_Click(object sender, EventArgs e)
{
if (!serialPort1.IsOpen)
{
serialPort1.PortName = cm_Port.Text;
serialPort1.BaudRate = 9600;
serialPort1.DataBits = 8;
try
{
serialPort1.Open();
bt_Open.Text = "关闭端口";
bt_Open.BackColor = Color.SkyBlue;
cm_Port.Enabled = false;
serialPort1.ReadExisting();
timer1.Start();
}
catch (System.Exception ex)
{
MessageBox.Show(this, "指定端口未能成功打开!", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
timer1.Stop();
System.Threading.Thread.Sleep(120);
if (!bSending)
{
serialPort1.ReadExisting();
serialPort1.Close();
bt_Open.Text = "打开端口";
bt_Open.BackColor = Color.LightGreen;
cm_Port.Enabled = true;
}
else
timer2.Start();
}
(注:标红代码为委托的关键代码)
2.通过委托(delegate)实现通过改变B窗口的某一数值来同步改变A窗口的某一数值;
通过改变Other窗口的端口数值,实现将主窗口的端口数值同步更改
首先, 在Other窗口定义一个 cm_PortValueChangedHandler委托和一个cmPortChange事件 用来在F_Main窗口订阅该事件,然后通过cm_Port_SelectedIndexChanged事件触发设置的mPortChange事件。
Other窗口代码:
public partial class Other : Form
{
public Other()
{
InitializeComponent();
}
public delegate void cm_PortValueChangedHandler(string selectedValue); // 声明委托
public static event cm_PortValueChangedHandler cmPortChange; // 声明事件
private void cm_Port_SelectedIndexChanged(object sender, EventArgs e)
{
string selectedValue = cm_Port.SelectedItem.ToString();//获取cm_Port的值
cmPortChange(selectedValue);//触发cmPortChange事件
}
}
其次,在主窗口声明Other窗口,然后在初始化位置订阅Other窗口的cmPortChange事件,F_Main窗口代码如下
public partial class F_Main : Form
{
public F_Main()
{
InitializeComponent();
//订阅窗口Other的cmPortChange事件
Other.cmPortChange += cmPortValueChanged;
}
Other other = new Other();
//Other cm_Port窗口数值改变,F_Main窗口cm_Port也改变
private void cmPortValueChanged(string selectedValue)
{
// 在这里更新第二个窗口的值
cm_Port.Text = selectedValue;
}
}
这样就实现了不同窗口的交互。
总结:在委托(delegate)里可以实现上述功能,步骤主要为:
1.在一窗口声明个委托A和事件B,用某一事件C触发该事件B;
2.在二窗口的初始化位置订阅一窗口的事件B,通过订阅将事件B与本窗口内某一事件D联系起来,这样就可以通过一窗口的C事件触发二窗口的D事件。
仅供参考,作者小白,如有不足及错误之处还请见谅。