Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 用C编写全局自定义事件#_C#_.net_Winforms_Events_Delegates - Fatal编程技术网

C# 用C编写全局自定义事件#

C# 用C编写全局自定义事件#,c#,.net,winforms,events,delegates,C#,.net,Winforms,Events,Delegates,我在这个表单上有一个winformwinform1和两个用户控件control1和control2 现在我想定义一个自定义事件,它在control1中引发/触发,在control2中接收。事件应该是全局的,而不是在control1中直接定义的。control2不应该知道control1的存在。 该事件也应由其他控件引发。这方面的C#代码如何?我需要类似于publisher类的东西吗?您所描述的看起来像,其中对象通过消息进行通信。这些消息可以实现为事件、回调或任何其他机制 您可以使用类似的实现,如

我在这个表单上有一个winformwinform1和两个用户控件control1control2

现在我想定义一个自定义事件,它在control1中引发/触发,在control2中接收。事件应该是全局的,而不是在control1中直接定义的。control2不应该知道control1的存在。
该事件也应由其他控件引发。这方面的C#代码如何?我需要类似于publisher类的东西吗?

您所描述的看起来像,其中对象通过消息进行通信。这些消息可以实现为事件、回调或任何其他机制

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

//注册特定的消息类型
Messenger.Default.Register(这个,DoSomething);
...
//当有人发送消息类型为的消息时调用
私有void DoSomething(消息类型)
{
// ...
}
//向为此消息类型注册的所有对象发送消息
senger.Default.Send(新类型的消息(…);
与静态事件相比,
Messenger
类的一大优势在于它使用弱引用,因此不会阻止订阅对象的垃圾收集,从而降低内存泄漏的风险


有关Messenger类的详细信息,请参见。您可以使用静态事件:

public static class MyGlobalEvent {
    public static event EventHandler MyEvent;

    public static void FireMyEvent(EventArgs args) 
    {
        var evt = MyEvent;
        if (evt != null)
            evt(args);
    }
}
按常规方式订阅:

MyGlobalEvent.MyEvent += args => Console.WriteLine("Event Was Fired.");
按你认为合适的方式开火:

MyGlobalEvent.FireMyEvent(new EventArgs());

所以,您可以使表单发布者(以及控件之间的中介者)成为订阅者,所有控件都将成为订阅者,并在事件发生时收到通知


控件中发生事件时,将通知窗体,窗体上的事件处理程序将通知订阅此事件的其他控件。

如果这样做,请小心内存泄漏。。。该事件将保留对其处理程序的强引用,并且如果您不取消订阅,将阻止收集它们。在这种情况下,该事件如何保留对其处理程序的强引用?你能详细说明一下吗?@AllSolutions,因为根据定义,事件包含对处理程序的引用。只是静态事件永远不会超出作用域,因为它们是静态的,而实例事件在收集时会与包含对象一起超出作用域。@AllSolutions:如何取消订阅静态事件。甚至-=似乎都不起作用
MyGlobalEvent.FireMyEvent(new EventArgs());