问题描述
我必须使用两个对象(电子邮件、移动设备)的集合传递数据。如果我单击按钮订阅者或取消订阅,如果我单击发布按钮,我输入的值应该被存储并显示到另一个表单。但是,我需要为此任务使用“委托”。
这是我处理输入值的表单
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace Q1
{
public partial class Form2 : Form
{
// declare delegate
public delegate void PublishMessageDel(ArrayList publist);
public PublishMessageDel publist = null;
public void PublishMessage(ArrayList subscribers)
{
publist.Invoke(subscribers);
}
public Form2()
{
InitializeComponent();
}
private void btnBackToMain_Click(object sender,EventArgs e)
{
// back to first form when the buttom is clicked
this.Hide();
Form1 mainWindow = new Form1();
mainWindow.ShowDialog();
this.Close();
}
private void txtEmailTo_Validating(object sender,CancelEventArgs e)
{
if (ckbEmailTo.Checked)
{
IsEmailFormmatch();
}
else if (!ckbEmailTo.Checked)
{
btnSubscribe.Enabled = false;
btnUnsubscribe.Enabled = false;
}
}
private void txtTextTo_Validating(object sender,CancelEventArgs e)
{
if (ckbTextTo.Checked)
{
IsMobileFormmatch();
}
else if (!ckbTextTo.Checked)
{
btnSubscribe.Enabled = false;
btnUnsubscribe.Enabled = false;
}
}
// check valid email and button visibility
public void IsEmailFormmatch()
{
string emailForm = (@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
if (!Regex.IsMatch(txtEmailTo.Text,emailForm))
{
MessageBox.Show("Invalid Email");
btnSubscribe.Enabled = false;
btnUnsubscribe.Enabled = false;
}
else
{
btnSubscribe.Enabled = true;
btnUnsubscribe.Enabled = true;
}
}
// check valid mobile and button visibility
public void IsMobileFormmatch()
{
string mobileForm = (@"\d{3}-\d{3}-\d{4}");
if (!Regex.IsMatch(txtTextTo.Text,mobileForm))
{
MessageBox.Show("Invalid Phone Number");
btnSubscribe.Enabled = false;
btnUnsubscribe.Enabled = false;
}
else
{
btnSubscribe.Enabled = true;
btnUnsubscribe.Enabled = true;
}
}
private void btnSubscribe_Click(object sender,EventArgs e)
{
ArrayList subscribers = new ArrayList();
if (ckbEmailTo.Checked)
{
subscribers.Add(txtEmailTo.Text);
}
else if (ckbTextTo.Checked)
{
subscribers.Add(txtTextTo.Text);
}
foreach (ArrayList list in subscribers)
{
PublishMessage(list);
}
}
private void btnUnsubscribe_Click(object sender,EventArgs e)
{
ArrayList subscribers = new ArrayList();
if (ckbEmailTo.Checked)
{
subscribers.Remove(txtEmailTo.Text);
}
else if (ckbTextTo.Checked)
{
subscribers.Remove(txtTextTo.Text);
}
}
}
}
我认为这部分有问题。
private void btnSubscribe_Click(object sender,EventArgs e)
{
ArrayList subscribers = new ArrayList();
if (ckbEmailTo.Checked)
{
subscribers.Remove(txtEmailTo.Text);
}
else if (ckbTextTo.Checked)
{
subscribers.Remove(txtTextTo.Text);
}
}
如果我点击发布按钮,这是表单,文本框应该向我显示在前一个表单中订阅的值。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace Q1
{
public partial class Form3 : Form
{
Form2 fm2;
public Form3()
{
InitializeComponent();
}
private void btnBackToMain3_Click(object sender,EventArgs e)
{
this.Hide();
Form1 mainWindow = new Form1();
mainWindow.ShowDialog();
this.Close();
}
// change button visibility when the textBox is empty or not
public void btnPublish_Click(object sender,EventArgs e)
{
Form2 fm2 = new Form2();
var value = fm2.publist += Subscribe;
txtSubscribers.Text += value;
//fm2.PublishMessage();
}
public void Subscribe(ArrayList list)
{
ArrayList subscribers = list;
txtSubscribers.Text += subscribers.ToString();
}
}
}
我想我没有正确使用委托并坚持与它链接..
解决方法
这是using delegates microsoft guide。
“委托是一种安全封装方法的类型,类似于 C 和 C++ 中的函数指针。与 C 函数指针不同,委托是面向对象的、类型安全和可靠的。委托的类型由名称定义代表。”
因此,在调用 arrSubscribers.Invoke(list);
之前,您应该在 Form3
中创建一个方法,该方法接受您的委托的签名(您将 ArrayList arrSubscribers
作为参数接收)并将引用添加到 {{ 1}}。
public void YourMethod(ArrayList arrSubscribers)
{
// 这里有订阅者的代码
}
fm2.arrSubscribers
或 fm2.arrSubscribers = YourMethod;
示例:
fm2.arrSubscribers += YourMethod;