Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.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#_Wpf_Mvvm_Weak References - Fatal编程技术网

C# 弱订阅通过反射获得的事件

C# 弱订阅通过反射获得的事件,c#,wpf,mvvm,weak-references,C#,Wpf,Mvvm,Weak References,我正在使用MVVM模式在WPF中创建一个MessageBox控件。此MessageBox将用于具有不同外观的多个应用程序,因此理想情况下,我希望代码不被代码隐藏 我试图在引发事件时显示MessageBox,该事件在MessageBox的声明中指定 例如,这将在窗口的XAML中指定,MessageBox将出现在该窗口中 <dialog:MessageBox ShowOnEvent="EventRaised" EventContext="{Binding}" Messa

我正在使用MVVM模式在WPF中创建一个
MessageBox
控件。此
MessageBox
将用于具有不同外观的多个应用程序,因此理想情况下,我希望代码不被代码隐藏

我试图在引发事件时显示
MessageBox
,该事件在
MessageBox
的声明中指定

例如,这将在窗口的XAML中指定,
MessageBox
将出现在该窗口中

<dialog:MessageBox
    ShowOnEvent="EventRaised"
    EventContext="{Binding}"
    Message="I am a message box"
    IconType="Warning"
    ButtonsType="YesNo" />
如预期的那样,在引发事件时显示消息框

但是,事件处理程序意味着当主窗口的视图被释放时,
MessageBox
ViewModel不会被GC调用。这意味着如果为主窗口创建了另一个视图,则会创建另一个
MessageBox
,因此如果引发事件,则会同时显示
MessageBox
s

我试图通过使用
WeakEventManager
来解决这个问题,但是指定
WeakEventManager
的实现应该只处理一个事件-这意味着我不能将事件名称作为字符串属性制作一个
showowneventmanager
,并使用该属性进行订阅

有没有人有什么好主意来解决这个问题?

默认情况下,使用弱引用实现事件。您需要能够更改发布事件的代码,以便在应用程序中实现这一点

链接页面上有适当的代码示例以及必需的流程图。事件聚合器的使用非常简单:您可以使用强类型负载发布
并在所需的任意位置订阅
。(而且它是)

默认情况下使用弱引用实现事件。您需要能够更改发布事件的代码,以便在应用程序中实现这一点


链接页面上有适当的代码示例以及必需的流程图。事件聚合器的使用非常简单:您可以使用强类型负载发布
并在所需的任意位置订阅
。(而且)

有一个弱事件并不能解决您的问题,因为在GC决定运行之前您不会取消订阅(除非您显式调用
GC.Collect()
)。正如威尔在评论中所建议的那样,您可以尝试在适当的时间取消订阅,或者更简单的方法是在显示自己之前让您的MessageBox检查它是否已加载


我不会担心MessageBox中的代码隐藏,除非您知道它会损害其可重用性的原因。只要MessageBox的使用者有一个MVVM友好的API,就可以让MessageBox代码直接引用其视图。

有一个弱事件不会解决您的问题,因为在GC决定运行之前您不会被取消订阅(除非您显式调用
GC.Collect()
)。正如威尔在评论中所建议的那样,您可以尝试在适当的时间取消订阅,或者更简单的方法是在显示自己之前让您的MessageBox检查它是否已加载


我不会担心MessageBox中的代码隐藏,除非您知道它会损害其可重用性的原因。只要MessageBox的使用者有一个MVVM友好的API,就可以让MessageBox代码直接引用其视图。

该控件应该是一个覆盖控件吗,或者它会带来一个
MessageBox
?@Will:这是一个覆盖-基本的
MessageBox
对我的需求来说不够灵活。既然你在视图上订阅了一个事件,为什么不呢,它会告诉你何时取消订阅这两个事件?这个控件应该是一个覆盖吗,或者它会带来一个
MessageBox
?@Will:这是一个覆盖层-基本的
MessageBox
对于我的需求来说不够灵活。既然你在视图上订阅了一个活动,为什么不呢,它会告诉你何时取消订阅这两个活动?多亏了你和@Will,听
unload
worked a treat:)多亏了你和@Will,听
unload
worked a treat:)
if (eventContext != null && showOnEvent != string.Empty)
{
    EventInfo eventInfo = eventContext.GetType ().GetEvent (showOnEvent);
    if (eventInfo != null)
    {
        eventInfo.AddEventHandler (eventContext, eventHandler);
    }
    else
    {
        Debug.WriteLine (string.Format ("Dialog: Couldn't find event {0} on {1}, check event name.", showOnEvent, eventContext));
    }
}