Sunday, March 4, 2012

Catch the silverlight closing event

Recently, I must catch the closing event of a silverlight application when users have not save their modifications. For this functionnality, I make a class with a boolean indicate pending changes.
public class ClosingHandler
{
    #region Properties
 
    private const string ScriptableObjectName = "OnBeforeUnload";
 
    /// <summary>
    /// Confirmation message
    /// </summary>
    public String Message { get; set; }
 
    private Boolean mHasPendingChange;
    /// <summary>
    /// Indicate pending change
    /// </summary>
    public Boolean HasPendingChange
    {
        get { return mHasPendingChange; }
        set
        {
            mHasPendingChange = value;
            if (value)
                Initialize();
            else
                Clear();
        }
    }
 
    #endregion
 
    #region Methods
 
    /// <summary>
    /// Initialization of the Hander
    /// </summary>
    public void Initialize()
    {
        //Out of Browser application
        if (Application.Current.IsRunningOutOfBrowser)
        {
            Application.Current.MainWindow.Closing +=
                new EventHandler<System.ComponentModel.ClosingEventArgs>(
                    MainWindow_Closing);
        }
        else    //In Browser application
        {
            HtmlPage.RegisterScriptableObject(ScriptableObjectName, this);
            string pluginName = HtmlPage.Plugin.Parent.Id;
 
            HtmlPage.Window.Eval(string.Format(
                @"window.onbeforeunload = function () {{
                var slApp = document.getElementById('{0}').getElementsByTagName('object')[0];
                var result = slApp.Content.{1}.OnBeforeUnload();
                if(result.length > 0)
                    return result;
                }}",
                pluginName, ScriptableObjectName)
                );
        }
    }
 
    /// <summary>
    /// Clear event handler and message
    /// </summary>
    public void Clear()
    {
        //Out of Browser application
        if (Application.Current.IsRunningOutOfBrowser)
        {
            Application.Current.MainWindow.Closing -=
                new EventHandler<System.ComponentModel.ClosingEventArgs>(
                    MainWindow_Closing);
        }
        else    //In Browser application
        {
            HtmlPage.RegisterScriptableObject(ScriptableObjectName, this);
            string pluginName = HtmlPage.Plugin.Parent.Id;
 
            HtmlPage.Window.Eval(@"window.onbeforeunload = ''");
        }
    }
 
    #endregion
 
    #region EventHandler
 
    /// <summary>
    /// MainWindow Closing event handler
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void MainWindow_Closing(object sender, System.ComponentModel.ClosingEventArgs e)
    {
        MessageBoxResult boxResult = MessageBox.Show(
                    Message, "Closing confirmation",
                    MessageBoxButton.OKCancel);
        if (boxResult == MessageBoxResult.Cancel)
            e.Cancel = true;
    }
 
    [ScriptableMember]
    public string OnBeforeUnload()
    {
        return Message;
    }
 
    #endregion
}

Source : http://mark.mymonster.nl/2011/01/30/how-to-cancel-the-closing-of-your-silverlight-application-in-browser-and-out-of-browser

No comments:

Post a Comment