【问题标题】:How to use delegate and event?如何使用委托和事件?
【发布时间】:2016-09-16 21:59:18
【问题描述】:

我正在尝试学习 C# 和一般编程,但遇到了问题。我已经尝试搜索答案但失败了,所以如果我复制另一个主题,我很抱歉。

我有 1 个窗体 (Form1)、外部类 (Class1)、窗体上的按钮和标签。 这个类是一个简单的文件粉碎机,从按钮点击开始。 Label1.text 应该从外部类更新,显示现在正在粉碎的文件。

我发现,我需要使用委托和事件才能正确实现,但我不知道如何正确使用它们。 代码在这里:

//Form1 
  private async void button2_Click(object sender, EventArgs e)
  {
  var task = new Task(() =>
  {
  check = true;
  bool success = FileUtilities.Shred(textBox1.Text);
  });
  task.Start();
  public void ChangeName(string text)
  {
  label3.Text = text; 
  }

  //Class1
  public static bool ShredFile(string filePath, bool shouldDelete = true)
  { 
  bool success = true; 
  try
  { 
  FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write);
  //Label1.text = filePath; - should be like that.

我尝试使用public void ChangeName 访问该属性,但没有成功。我不明白我应该在哪里创建一个委托、一个事件以及在哪里订阅这个事件。

更新:我发现了问题所在。我的程序中有几个线程,我无法通过我的班级访问表单上的标签。我不得不使用回调,然后订阅和事件完美运行。感谢您,Thorsten Dittmar,展示了正确的方式。

【问题讨论】:

标签: c# events delegates


【解决方案1】:

实际上有几种方法可以实现您想要的。我会采用以下方式,因为它最容易实现并且不涉及任何回调;-)

这背后的基本思路是:将 UI 更新留给维护 UI 的类。其他一切都是工具,甚至不需要知道是否有 UI。

如果您的 UI 代码中有触发粉碎文件的地方,请执行三个步骤:

  1. 更新您的 UI,例如显示正在粉碎的文件的文件名(UI 类)
  2. 粉碎文件(工具类)
  3. 显示粉碎操作的成功或失败(UI 类)

看到了吗?没有事件:-)

但您的问题是如何实际创建和使用事件,所以....

通常一个事件在发送方由两部分组成:

  • event
  • 引发事件的方法

例如,您可以像这样声明它们。

public class EventSender
{
    public event EventHandler<EventArgsType> MyEvent;

    protected void OnMyEvent(...)
    {
        if (MyEvent != null)
            MyEvent(this, new EventArgsType(...));
    }
}

EventArgsTypeEventArgs 的子类,您可以使用它将信息从发送方传递到接收方。一个例子:

public class EventSender
{
    public class EventArgsType : EventArgs
    {
        public EventArgsType(string fileName) : base()
        {
            FileName = fileName;
        }

        public string FileName
        {
            get;
            private set;
        }
    }

    public event EventHandler<EventArgsType> MyEvent;

    protected void OnMyEvent(string filename)
    {
        if (MyEvent != null)
            MyEvent(this, new EventArgsType(filename));
    }
}

无论何时应该引发事件,从EventSender调用OnMyEvent 方法就足够了。

现在接收器需要将自己附加到事件上,然后每当触发事件时都会调用一个方法。示例

public class Receiver
{
    private EventSender _sender;

    public Receiver()
    {
        _sender = new EventSender();
        _sender.MyEvent += HandleMyEvent;
    }

    private void HandleMyEvent(object sender, EventSender.EventArgsType e)
    {
        // Do something with e.FileName
    }
}

那么在你的情况下我会怎么做?我会创建一个 nonstaticFileShredder,它实现一个或多个与示例类似的事件,并具有一个 nonstatic 方法来粉碎文件。

在您的 UI 中开始任何任务之前,我将创建此类的一个实例,附加所需的事件处理程序,然后我将使用该实例来分解文件。在 UI 类的事件处理程序中,更改标签和内容。

【讨论】:

  • 我在工具类中的FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Write); 之后添加了OnMyEvent(filePath),它始终返回null。它不能引发事件。
  • 那么,首先创建一个示例项目以了解其工作原理,然后然后尝试将您学到的知识整合到您当前的项目中?此外,在您的示例中,即使做所有这些也没有意义。在开始任务之前,只需将标签的文本设置为 TextBox 中的文件名。完成-
  • 这是我的示例项目)textBox 不是要粉碎的文件,而是位置。该测试文件夹中有 1k 个文件,只有工具类知道这些路径。但你是对的,我需要先了解它。谢谢你这么详细的回答。
猜你喜欢
  • 2014-03-16
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
  • 2011-02-16
  • 1970-01-01
相关资源
最近更新 更多