MainWindow.Closing事件并不总是在Silverlight 4 OOB应用程序中引发

时间:2010-08-28 16:07:41

标签: silverlight silverlight-4.0

我制作了一个相当复杂的Silverlight 4浏览器外应用程序。我的一个主视图模型为Application.Current.MainWindow.Closing事件添加了一个事件处理程序。 这在最初运行应用程序时工作正常。它可以取消关闭操作。

但是,有时在执行显示和关闭ChildWindow等操作后,MainWindow的Closing事件不再调用我的处理程序。

在调试器中,我向MainWindow的底层结束事件委托添加了一个监视。在显示ChildWindow之前它不是null。然后在ChildWindow关闭后有时,委托为空。这就解释了为什么我的处理程序不再被调用。但为什么这个代表被搞砸了呢?为什么它偶尔会发生? 我的应用程序不会在任何时候取消绑定我的事件处理程序。

这是我正在观看的代表:

System.Windows.Application.Current.MainWindow.m_closingEvent

其他东西:我正在使用Caliburn Micro

3 个答案:

答案 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;
        }
    };
}