Silverlight - Prevent users from losing changes by using the browser back button

image

Do you know how to prevent users from losing changes in your Silverlight application, if they click the "back button" or "close browser" button?

#1
Add this method to your main page (if using Silverlight navigation framework) or user control (if Silverlight app)

 
        public void RegisterOnBeforeUnload()
        {
            //Register Silverlight object for availability in Javascript.
            const string scriptableObjectName = "SilverlightClientControl"; // <-- THIS IS THE NAME OF YOUR HOSTING OBJECT IN THE WEB PAGE
            HtmlPage.RegisterScriptableObject(scriptableObjectName, this);


            //Start listening to Javascript event.
            string pluginName = HtmlPage.Plugin.Id;
            HtmlPage.Window.Eval(string.Format(
                @"window.onbeforeunload = function () {{
                   var slApp = document.getElementById('{0}');
                   var result = slApp.Content.{1}.OnBeforeUnload();
                   if(result.length > 0)
                       return result;
               }}", pluginName, scriptableObjectName)
                    );
        }  

Figure: Method that will register your Silverlight object for availability in JavaScript and start listening on JavaScript events

 

#2
Call the top method "RegisterOnBeforeUnload" in the constructor of your control

 

#3
Add this to the same user control

        [ScriptableMember] 
        public string OnBeforeUnload() 
        { 
            if (MainViewModel.HasUnsavedChanges) 
                return "You have unsaved changes! Please save them before leaving the application."; 
            return string.Empty; 
        } 
  

Figure: "MainViewModel.HasUnsavedChanges" is the flag if the exit is allowed without warning or not (= user clicks on "Exit Auction" which exits normally)

#5
Done

 

image 
Figure: Now when you want the users is in the middle of a change and navigates away, he gets a nice warning!
This fires on the "Back button", "Close tab" or "Close browser", which is awesome!

 

 

image

PS
You could even automagically save the changes when the user closes the browser!!

12 comments:

Unknown said...

Shouldn't this be..
if (MainViewModel.HasUnsavedChanges == true)
...

Peter Gfader said...

Well spotted Juri

This happens when you have to fix production code for blog posts...

louis vuitton zipped purse said...

Nice ! but how to the code for the page ~!

Anonymous said...

This is a great post - very helpful - Thanks

Anonymous said...

Perfect! Thank you :)

Ashok said...

Hi Peter Gfader,
I got below problem when am using ur above code.

Got Problem in the line of code:
-----------------------------------
HtmlPage.RegisterScriptableObject(scriptableObjectName, this);

Erroe is:
-----------------------------------
Object does not have a ScriptableAttribute or any scriptable members.

Please solve my prolem ASAP. Thanks in advance.

-Ashok

Peter Gfader said...

@Ashok
Check that the Silverlight object has an ID in the hosting page.
Check that you are using the right ID.

See this hint in code above:
// <-- THIS IS THE NAME OF YOUR HOSTING OBJECT IN THE WEB PAGE

Mbcoop said...

Many thanks Peter!

Ajay singh said...

Hi Peter.
may you explain MainViewModel.HasUnsavedChanges
i am not getting this line where you have declare this hasUnsavedChanges?
Please reply as soon as possible.

Peter Gfader said...

@Ajay

HasUnsavedChanges is a property on your ViewModel that tells you if the ViewModel is in "dirty" state.

you can just "return true" for testing purposes....

Ajay singh said...

Hi again.
i am new in silverlight and i am fresher in development field. my boss told me that you have to do any how @boss"i don't know how you will do".
so my question is when we will set the property true to the HasUnsavedChanges or we have to set that property manually to true when user is going to type any thing on the silverlight page.
please help me peter sir. otherwise i don't know what will happen with me.
May you send me the example if it is possible.
Thanks,
Ajay Singh

Peter Gfader said...

@Ajay
If you are using a "fancy" framework like Prism you might be able to just use "IsDirty" on the Object that you are binding to.

Otherwise manual. You might be able to solve this elegantly by hooking into INotifyPropertyChanged

Post a Comment

Latest Posts

Popular Posts