OOB模式下Exit事件的处理
在Silverlight中,当用户退出程序时,我们一般需要在Exit事件中保存用户的相关资料,本文主要讲述在OOB模式下的解决方案.
按照一般的思路,在程序退出时,我们会在Exit事件中与服务器交互,如下代码:
private void Application_Exit(object sender, EventArgs e)
{
TestClient proxy=new TestClient();
proxy.SaveWorkCompleted += (obj,arg) => { };
proxy.SaveWorkAsync();
}
但是,调试下来你会发现,根本没有执行proxy.SaveWorkCompleted,经过查找资料确认在Exit()中是不支持WCF的.见MSDN:
经过一番搜索,在OOB模式下,我们可以用Closing方式进行处理:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
if(App.Current.IsRunningOutOfBrowser)
{
App.Current.MainWindow.Closing += MainWindowClosing;
}
}
private bool _isLoginOut=false;
void MainWindowClosing(object sender, System.ComponentModel.ClosingEventArgs e)
{
if(!_isLoginOut)
{
e.Cancel = true;
TestClient proxy = new TestClient();
proxy.SaveWorkCompleted += (obj, arg) =>
{
_isLoginOut = true;
App.Current.MainWindow.Close();
};
proxy.SaveWorkAsync();
}
}
}
当用户点击OOB窗口的关闭按钮时,会首先触发Closing事件,执行时首先会取消当前的Exit事件,即e.Cancel=true,当WCF执行完后,调用App.Current.MainWindow.Close()关闭程序
不过用这种方式,你需要提升OOB的权限,否则在执行App.Current.MainWindow.Close()时会报出安全异常
提升OOB权限,意味着需要对xap进行签名,用户安装时将看到这个界面,@~@.没办法,上帝给你开了一扇门,也会关个门的.
那么还有一种情况,是调用ChildWindow或者导航时,导致Closing不触发,具体的情景我就不叙述了.关键的代码是将ManinWindow保存
public static object _mainFrame;
public MainPage()
{
InitializeComponent();
if(App.Current.IsRunningOutOfBrowser)
{
_mainFrame = App.Current.MainWindow;
App.Current.MainWindow.Closing += MainWindowClosing;
}
}