1

这花了我好几天的时间来开发一个在类与代表和事件之间进行通信的演示。我想知道这是否是完成类之间数据传递的最佳实践方式。如果有更好的方法请告诉我。具体来说,如果子类中发生了某些事情,您如何将其返回到主类。这在通过将用户界面与业务逻辑级别和数据访问级别分离来进行 n 层架构时特别有用。

我有一个包含 3 个文本框的表单:tb1、tb2 和 tbAnswer。我还有一个按钮,上面写着“添加”,它只是 button1。

主要形式是:

namespace DelegateTest
{
    public delegate void ShowMessage(object sender, Form1.AnswerEventArgs e);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void a_OnShowMessage(object sender, AnswerEventArgs e)
        {
            tbAnswer.Text = e.answer;
        }

        public class AnswerEventArgs :EventArgs
        {
            public string answer { get; set; }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            AddClass a = new AddClass();
            a.OnShowMessage += new ShowMessage(a_OnShowMessage);
            a.AddMe(Convert.ToInt16(tb1.Text), Convert.ToInt16(tb2.Text));
        }
    }
}

并且名为 AddClass.cs 的子表单是:

namespace DelegateTest
{
    class AddClass
    {
        public event ShowMessage OnShowMessage;
        public void AddMe(int a, int b)
        {
            Form1.AnswerEventArgs e = new Form1.AnswerEventArgs();
            e.answer = (a+b).ToString();
            OnShowMessage(this, e);
        }
    }
}
4

1 回答 1

2

除了两个细节外,您的方法是合理的。

首先,NullPointerException如果在添加任何处理程序之前引发您的事件,则会发生 a 。您可以通过以下两种方式之一解决此问题。

1)制作本地副本(以避免竞争条件)并检查它是否为空:

var showMessage = OnShowMessage;
if (showMessage != null)
{
    showMessage(this, e);
}

2)将您的事件初始化为空委托:

public event ShowMessage OnShowMessage = delegate { };

其次,在这种情况下,您不需要声明自己的委托。EventHandler您可以使用自己的事件参数简单地创建一个标准:

public event EventHandler<Form1.AnswerEventArgs> OnShowMessage = delegate { };

有关详细信息,请参阅如何:发布符合 .NET Framework 准则的事件。

于 2013-07-18T17:14:34.923 回答