c# - 如何跨类发布和订阅事件

标签 c# events delegates

目标:当 udp 或 tcp 使用其发送方法时更改表单上的图像

问题:我不知道如何正确设置事件、事件处理程序和委托(delegate)

发送接口(interface)

interface ISendData
{
  void Send();
}

TCP 连接类

//Need some type of delegate??

public class TCPconnection : ISendData
{
   void Send()
   {
     //how invoke/fire a send Event?
   }
}

UDP 连接类

//Need some type of delegate??

public class UDPConnection : ISendData
{
   void Send()
   {
     //how invoke/fire a send event?
   }
}

“应该”订阅查看触发事件的 winform

public class myForm
{
   private DataWatcher datawatcher = new DataWatcher();
   private Image statusIndicator = null;

   public myform()
   {
     initComponents();

     datawatcher.DataSendActive += new DataWatcherSendHandler(DataSending);
     datawatcher.DataSendInactive += new DataWatcherSendHandler(NoDataSending);
   }

   public void DataSending(object sender, DataWatcherArgs e)
   {
      statusIndicator = Properties.resources.greenLight;
   }

   public void NoDataSending(object sender, DataWatcherArgs e)
   {
      statusIndicator = Properties.resources.redLight;
   }

}

事件/事件处理程序??但我真的不知道我在这里做了什么来完成这项工作

 public delegate void EventHandler(object sender, EventArgs e);

    class DataWatcher
    {
        public event EventHandler DataSendActive;
        public event EventHandler DataSendInactive;

        protected virtual void onDataSendActive(System.EventArgs e)
        {
            if (DataSendActive != null)
            {
                DataSendActive(this, e);
            }
        }
        protected virtual void onDataSendInactive(System.EventArgs e)
        {
            if (DataSendInactive != null)
            {
                DataSendInactive(this, e);
            }
        }
     }

最佳答案

有许多约定用于执行此操作。这是我的小实现。

public enum ActivityState
{
    Sending,
    Receiving,
    Idle
}

public interface IDataTransferManager
{
    // This event will fire when the activity state changes.
    // note that Action<T> is introduced in .NET 3.5
    // if you're using .NET 2.0, you can use a delegate.
    event Action<ActivityState> DataActivityStateChange;
   

    void Send(byte[] data);
    //byte[] Receive(); 
    // ... more methods ... //

}

现在 TcpConnection 类将实现它。

public class TcpConnection : IDataTransferManager
{
    public event Action<ActivityState> DataActivityStateChange;

    public void Send(byte[] data)
    {
        // we're sending data. fire the change event
        FireDataActivityStateChange(ActivityState.Sending);

        //TODO: send the data

        // we're done sending. Fire the change event
        FireDataActivityStateChange(ActivityState.Idle);
    }



    private void FireDataActivityStateChange(ActivityState state)
    {
        // helper method, so I don't have to check the event 
        // to avoid null reference exceptions.
        if (DataActivityStateChange != null)
            DataActivityStateChange(state);
    }

}

这是您的表单的设置。

class MyForm // :Form
{
    IDataTransferManager dataManager;

    public MyForm()
    {   // here, usually an instance will be passed in, 
        // so there's only one instance throughout the application.
        // let's new up an instance for explanation purposes.
        dataManager = new TcpConnection();

        dataManager.DataActivityStateChange += (state) => 
        {
            // NOTE: if you don't like inline, 
            // you can point this labda to a method.
            
            switch (state)
            {
                case ActivityState.Sending:
                    // change the image to the spinning toilet ball
                    break;
                case ActivityState.Receiving:
                    // change the image to the spinning toilet ball, but reverse :P
                    break;
                case ActivityState.Idle:
                    // hide it ?
                    break;
            }
        };
    }
}

关于c# - 如何跨类发布和订阅事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15456387/

相关文章:

c# - UIAutomation 和远程桌面连接

c# - 来自数据库的 ASP.NET MVC 下拉列表

c# - WebControl 和 CompositeControl 之间的区别?

c# - 传递运算符和其他参数

c# - 将图像转换为 Base64 字符串

c# - 导出到 excel 抛出 System.OutOfMemoryException

php - 在 FOSUserBundle 中,如何在 REGISTRATION_COMPLETED 事件上初始设置用户角色?

Ruby - 主线程退出时不要终止进程

c# - 在 C# 中使用委托(delegate)的两种方式有什么区别(有 new 关键字和没有)

ios - Swift:从其他 Viewcontroller 调用 PageViewController 中的函数