【发布时间】:2011-07-18 13:39:11
【问题描述】:
我正在使用 MVVM 模式在 WPF 中制作MessageBox 控件。这个MessageBox 将用于具有不同外观的多个应用程序中,因此理想情况下我希望将代码保持在代码隐藏之外。
我试图让MessageBox 在引发事件时出现,在MessageBox 的声明中指定。
例如,这将在应出现MessageBox 的窗口的 XAML 中指定。
<dialog:MessageBox
ShowOnEvent="EventRaised"
EventContext="{Binding}"
Message="I am a message box"
IconType="Warning"
ButtonsType="YesNo" />
目前的工作方式:在MessageBox ViewModel 中,我使用反射来获取事件的EventInfo,然后直接订阅:
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));
}
}
这会在引发事件时按预期显示MessageBox。
然而,事件处理程序意味着MessageBox ViewModel 在主窗口的 View 被释放时不会被 GC。这意味着如果为主窗口创建另一个视图,则会创建另一个 MessageBox,因此如果引发事件,两个 MessageBoxs 都会显示。
我尝试使用WeakEventManager 来解决这个问题,但Weak Event Patterns documentation 指定WeakEventManager 的实现应该只处理一个事件——这意味着我不能使用事件名称创建ShowOnEventEventManager作为字符串属性并使用它进行订阅。
有没有人对解决此问题的最佳方法有任何想法?
【问题讨论】:
-
该控件是否应该是一个叠加层,还是会显示一个
MessageBox? -
@Will:这是一个覆盖 - 基本的
MessageBox对我的需求来说不够灵活。 -
既然您在 View 上订阅了一个事件,为什么不subscribe to another event 也一样,它会告诉您何时取消订阅?
标签: c# wpf mvvm weak-references