我制作了一个相当复杂的Silverlight 4浏览器外应用程序。我的一个主视图模型为Application.Current.MainWindow.Closing事件添加了一个事件处理程序。 这在最初运行应用程序时工作正常。它可以取消关闭操作。
但是,有时在执行显示和关闭ChildWindow等操作后,MainWindow的Closing事件不再调用我的处理程序。
在调试器中,我向MainWindow的底层结束事件委托添加了一个监视。在显示ChildWindow之前它不是null。然后在ChildWindow关闭后有时,委托为空。这就解释了为什么我的处理程序不再被调用。但为什么这个代表被搞砸了呢?为什么它偶尔会发生? 我的应用程序不会在任何时候取消绑定我的事件处理程序。
这是我正在观看的代表:
System.Windows.Application.Current.MainWindow.m_closingEvent
其他东西:我正在使用Caliburn Micro
答案 0 :(得分:8)
我遇到了完全相同的问题。我们有一个运行OOB的大型Silverlight应用程序。
出于某种原因,运行一段时间后m_ClosingEvent被清空了。我无法找到此问题的原因,但我认为这可能与我们更改根视觉或我们显示的所有子窗口有关。
我正在使用ApplicationWrapper类。
public class ApplicationWrapper : IApplicationWrapper
{
public void Initialize()
{
HookCloseEvent(true);
}
private void HookCloseEvent(bool hook)
{
if (hook && IsRunningOutOfBrowser)
{
Application.Current.MainWindow.Closing += OnClosing;
}
else
{
if (IsRunningOutOfBrowser)
{
Application.Current.MainWindow.Closing -= OnClosing;
}
}
}
private void OnClosing(object sender, ClosingEventArgs e)
{
InvokeClosing(e);
}
... etc..
}
从未调用过InvokeClosing方法。但是当我把它改成
时public class ApplicationWrapper : IApplicationWrapper
{
private Window _mainWindow;
public void Initialize()
{
if(IsRunningOutOfBrowser)
{
_mainWindow = Application.Current.MainWindow;
}
HookCloseEvent(true);
}
private void HookCloseEvent(bool hook)
{
if (hook && IsRunningOutOfBrowser)
{
_mainWindow.Closing += OnClosing;
}
else
{
if (IsRunningOutOfBrowser)
{
_mainWindow.Closing -= OnClosing;
}
}
}
private void OnClosing(object sender, ClosingEventArgs e)
{
InvokeClosing(e);
}
... etc...
}
m_ClosingEvent不是空的。
因此,尝试将“初始”MainWindow存储在一个字段中,并检查是否能解决您的问题。
答案 1 :(得分:3)
为什么不注册服务而不是挂钩?创建一个实现IApplicationService和IApplicationLifetimeAware的类。后者为您提供“onexiting”和“onexited”事件。通过在App.xaml中调用的部分中指向服务,将服务放在应用程序中。我已经将它用于许多项目,并且从未遇到过没有被调用的退出方法的问题。
答案 2 :(得分:1)
好吧,拔出我的头发和许多错误的开始I finally found the answer - 它似乎是Closing事件的已知错误,OOB和ChildWindows打开/关闭......
诀窍是存储对主窗口的静态引用:
public MainPage()
{
InitializeComponent();
Loaded += MainPage_Loaded;
}
private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
//you have to store this to work around the bug
//http://forums.silverlight.net/forums/p/185664/424174.aspx
_mainWindow = App.GetApp.MainWindow;
App.GetApp.MainWindow.Closing += (s, e1) =>
{
if (UIUtilities.ShowMessage("Would you like to exit AMT Mobile?", "Exit Application", MessageBoxButton.OKCancel) != MessageBoxResult.OK)
{
e1.Cancel = true;
}
};
}