在C#中编写全局自定义事件

Elm*_*mex 6 .net c# events delegates winforms

我有一个WinForm winform1和2用户控制控制1控制2这种形式

现在我想定义一个自定义事件,它在control1中被引发/触发并在control2中被接收.该事件应该是全局的,而不是在control1中直接定义.control2不应该知道control1的存在.该事件也应由其他控件提出.C#代码怎么样?我需要像发布者类这样的东西吗?

Kir*_*oll 9

您可以使用静态事件:

public static class MyGlobalEvent {
    public static event EventHandler MyEvent;

    public static void FireMyEvent(EventArgs args) 
    {
        var evt = MyEvent;
        if (evt != null)
            evt(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

以通常的方式订阅:

MyGlobalEvent.MyEvent += args => Console.WriteLine("Event Was Fired.");
Run Code Online (Sandbox Code Playgroud)

你认为合适的火:

MyGlobalEvent.FireMyEvent(new EventArgs());
Run Code Online (Sandbox Code Playgroud)

  • 如果你这样做,请注意内存泄漏...事件将对其处理程序有强烈的引用,并且如果你不取消订阅将阻止它们被收集 (4认同)

Tho*_*que 8

您描述的内容类似于Mediator模式,其中对象通过消息进行通信.这些消息可以实现为事件,回调或任何其他机制.

您可以使用类似MVVM LightMessenger类的实现(此框架旨在与WPF和Silverlight一起使用,但您可以获取此特定类的代码并在WinForms中使用它)

// Register for a specific message type
Messenger.Default.Register<TypeOfTheMessage>(this, DoSomething);
...

// Called when someone sends a message of type TypeOfTheMessage
private void DoSomething(TypeOfTheMessage message)
{
    // ...
}

// Send a message to all objects registered for this type of message
Messenger.Default.Send(new TypeOfTheMessage(...));
Run Code Online (Sandbox Code Playgroud)

Messenger类相对于静态事件的一大优点是它使用弱引用,因此它不会阻止订阅对象的垃圾收集,从而降低了内存泄漏的风险.

有关课程的详细信息,请参阅此链接Messenger