如何使用委托和事件?

时间:2016-09-14 13:19:50

标签: c# events delegates

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

我在Form上有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 ,以正确的方式展示。

1 个答案:

答案 0 :(得分:0)

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

这背后的基本原则是:将UI更新保留给维护UI的类。其他一切都是工具,甚至不需要知道是否有用户界面。

如果你的UI代码中有一个点触发了粉碎文件,请执行以下三个步骤:

  1. 更新您的UI,例如显示正在粉碎的文件的文件名(UI类)
  2. 切碎文件(工具类)
  3. 显示碎化操作(UI类)的成功或失败
  4. 请参阅?没有事件:-)

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

    一般情况下,事件由发件人方两部分组成:

    • 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));
        }
    }
    

    每当提出事件时,只需在OnMyEvent 类中调用EventSender方法即可。

    现在接收器需要将自己附加到事件,然后只要触发事件就会调用一个方法。实施例

    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
        }
    }
    

    那么在你的情况下我会做什么?我创建了一个非静态FileShredder,它实现了一个或多个类似于示例的事件,并且有一个非静态方法来粉碎文件。

    在UI中启动任何任务之前,我将创建此类的实例,附加所需的事件处理程序,然后我将使用该实例来粉碎文件。在UI类的事件处理程序中,更改标签和内容。