代表确认和退订问题
delegate with confirm and unsubscribe issue
我正在为 delegate/event 苦苦挣扎。我很可能不了解整个情况。
为了论证,我有两种形式:形式1和形式2。
问题:
- 如何适当取消订阅事件“frm2.ButtonClicked -= new PassMsg(MsgReceivedFromFrm2);”?
- 如果我终止 form 2,我仍然会得到确认 message.why 这是否发生了?
:
public partial class Form1 : Form
{
PassMsg NotifyFrm2EventHandler; // Delegate definition
PassMsgWithConfirm NotifyFrm2WithConfirmEventHandler; // Delegate with return definition
event PassMsg NotifyFrm2AsEvent; // Event definition
int i;
public Form1()
{
InitializeComponent();
i = 0;
}
private void btn_InitializeFrm2_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
NotifyFrm2EventHandler = new PassMsg(frm2.ReceiveMsgFromForm1); // setup link from Form 1 to Form 2
NotifyFrm2WithConfirmEventHandler = new PassMsgWithConfirm(frm2.ReceiveMsgFromForm1withConfirm); // setup link from Form 1 to Form 2
NotifyFrm2AsEvent += new PassMsg(frm2.ReceiveMsgFromForm1); // setup link from Form 1 to Form 2
frm2.ButtonClicked += new PassMsg(MsgReceivedFromFrm2); // setup link from Form 2 to Form 1
frm2.Show();
}
private void btn_Send2Frm2_Click(object sender, EventArgs e)
{
i++;
NotifyFrm2EventHandler?.Invoke("message from form 1 with index " + i.ToString()); // Notification by Call
}
private void btn_Send2Frm2WithConfirm_Click(object sender, EventArgs e)
{
i++;
bool confirmed = (bool)(NotifyFrm2WithConfirmEventHandler?.Invoke("message from form 1 with confirm with index" + i.ToString())); // Notification by Call
if (confirmed)
{
MessageBox.Show("confirmed.");
}
}
private void btn_sendAsEvent_Click(object sender, EventArgs e)
{
i++;
NotifyFrm2AsEvent?.Invoke("message from form 1 as event with index" + i.ToString()); // Notification by Call
}
void MsgReceivedFromFrm2(string input)
{
label1.Text = input;
}
}
和form2代码:
public partial class Form2 : Form
{
public event PassMsg ButtonClicked; // Event definition
public Form2()
{
InitializeComponent();
}
public void ReceiveMsgFromForm1(string input)
{
label1.Text = input;
}
public bool ReceiveMsgFromForm1withConfirm(string input)
{
label1.Text = input;
return true;
}
private void button1_Click(object sender, EventArgs e)
{
ButtonClicked("Message from Form 2");
}
}
引发事件 (Invoke) 的 class(本例中为表单)始终定义事件。调用、触发或引发事件就像广播消息一样。这个class就叫做发布者。因此,在大多数情况下,事件是 public
。
与 +=
一起附加到此事件的另一个 class 是订阅者。它是这条消息的接收者。
您以某种方式混淆了发布者和订阅者。
事件类似于自动 属性 但对于委托而言。所以,
public event MessageEventHandler Message;
定义一个事件Message
。相当于
private MessageEventHandler _messageEventHandler;
public event MessageEventHandler Message
{
add
{
_messageEventHandler += value;
}
remove
{
_messageEventHandler -= value;
}
}
因此,您不需要这些明确的事件处理程序字段声明。此外,没有必要使用 new
显式创建委托。 += EventHandlerMethod
一个人就好
如果要Form2
处理来自Form1
的事件,最好将Form1
作为构造函数参数传递给Form2
。 Form2
中的事件处理程序可以是私有的。是否订阅该事件也取决于 Form2
。控件定义了许多事件,但作为接收者的表单只订阅了其中的少数事件。
发送方:
public class MessageEventArgs : EventArgs
{
public string Message { get; set; }
}
public delegate void MessageEventHandler(object sender, MessageEventArgs e);
public partial class Form1 : Form
{
public event MessageEventHandler Message;
... constructor and other stuff not shown here.
private void btnInitializeFrm2_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(this);
frm2.Show();
}
private void btnSendMessage_Click(object sender, EventArgs e)
{
// You don't care who is receiver. You might have many receivers or none.
OnMessage($"Message from form 1 with index {i}");
}
private virtual void OnMessage(string message)
{
Message?.Invoke(new MessageEventArgs { Message = message });
}
}
订阅者:
public partial class Form2 : Form
{
private Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
form1.Message += Form1_Message;
}
private void Form1_Message(object sender, MessageEventArgs e)
{
MessageBox.Show("Form2 got message: " + e.Message);
}
private void btnUnsubscribe_Click(object sender, EventArgs e)
{
_form1.Message -= Form1_Message;
}
}
另见
我正在为 delegate/event 苦苦挣扎。我很可能不了解整个情况。 为了论证,我有两种形式:形式1和形式2。
问题:
- 如何适当取消订阅事件“frm2.ButtonClicked -= new PassMsg(MsgReceivedFromFrm2);”?
- 如果我终止 form 2,我仍然会得到确认 message.why 这是否发生了?
:
public partial class Form1 : Form
{
PassMsg NotifyFrm2EventHandler; // Delegate definition
PassMsgWithConfirm NotifyFrm2WithConfirmEventHandler; // Delegate with return definition
event PassMsg NotifyFrm2AsEvent; // Event definition
int i;
public Form1()
{
InitializeComponent();
i = 0;
}
private void btn_InitializeFrm2_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
NotifyFrm2EventHandler = new PassMsg(frm2.ReceiveMsgFromForm1); // setup link from Form 1 to Form 2
NotifyFrm2WithConfirmEventHandler = new PassMsgWithConfirm(frm2.ReceiveMsgFromForm1withConfirm); // setup link from Form 1 to Form 2
NotifyFrm2AsEvent += new PassMsg(frm2.ReceiveMsgFromForm1); // setup link from Form 1 to Form 2
frm2.ButtonClicked += new PassMsg(MsgReceivedFromFrm2); // setup link from Form 2 to Form 1
frm2.Show();
}
private void btn_Send2Frm2_Click(object sender, EventArgs e)
{
i++;
NotifyFrm2EventHandler?.Invoke("message from form 1 with index " + i.ToString()); // Notification by Call
}
private void btn_Send2Frm2WithConfirm_Click(object sender, EventArgs e)
{
i++;
bool confirmed = (bool)(NotifyFrm2WithConfirmEventHandler?.Invoke("message from form 1 with confirm with index" + i.ToString())); // Notification by Call
if (confirmed)
{
MessageBox.Show("confirmed.");
}
}
private void btn_sendAsEvent_Click(object sender, EventArgs e)
{
i++;
NotifyFrm2AsEvent?.Invoke("message from form 1 as event with index" + i.ToString()); // Notification by Call
}
void MsgReceivedFromFrm2(string input)
{
label1.Text = input;
}
}
和form2代码:
public partial class Form2 : Form
{
public event PassMsg ButtonClicked; // Event definition
public Form2()
{
InitializeComponent();
}
public void ReceiveMsgFromForm1(string input)
{
label1.Text = input;
}
public bool ReceiveMsgFromForm1withConfirm(string input)
{
label1.Text = input;
return true;
}
private void button1_Click(object sender, EventArgs e)
{
ButtonClicked("Message from Form 2");
}
}
引发事件 (Invoke) 的 class(本例中为表单)始终定义事件。调用、触发或引发事件就像广播消息一样。这个class就叫做发布者。因此,在大多数情况下,事件是 public
。
与 +=
一起附加到此事件的另一个 class 是订阅者。它是这条消息的接收者。
您以某种方式混淆了发布者和订阅者。
事件类似于自动 属性 但对于委托而言。所以,
public event MessageEventHandler Message;
定义一个事件Message
。相当于
private MessageEventHandler _messageEventHandler;
public event MessageEventHandler Message
{
add
{
_messageEventHandler += value;
}
remove
{
_messageEventHandler -= value;
}
}
因此,您不需要这些明确的事件处理程序字段声明。此外,没有必要使用 new
显式创建委托。 += EventHandlerMethod
一个人就好
如果要Form2
处理来自Form1
的事件,最好将Form1
作为构造函数参数传递给Form2
。 Form2
中的事件处理程序可以是私有的。是否订阅该事件也取决于 Form2
。控件定义了许多事件,但作为接收者的表单只订阅了其中的少数事件。
发送方:
public class MessageEventArgs : EventArgs
{
public string Message { get; set; }
}
public delegate void MessageEventHandler(object sender, MessageEventArgs e);
public partial class Form1 : Form
{
public event MessageEventHandler Message;
... constructor and other stuff not shown here.
private void btnInitializeFrm2_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(this);
frm2.Show();
}
private void btnSendMessage_Click(object sender, EventArgs e)
{
// You don't care who is receiver. You might have many receivers or none.
OnMessage($"Message from form 1 with index {i}");
}
private virtual void OnMessage(string message)
{
Message?.Invoke(new MessageEventArgs { Message = message });
}
}
订阅者:
public partial class Form2 : Form
{
private Form1 _form1;
public Form2(Form1 form1)
{
InitializeComponent();
_form1 = form1;
form1.Message += Form1_Message;
}
private void Form1_Message(object sender, MessageEventArgs e)
{
MessageBox.Show("Form2 got message: " + e.Message);
}
private void btnUnsubscribe_Click(object sender, EventArgs e)
{
_form1.Message -= Form1_Message;
}
}
另见