Blog of Keith Craig, containing my thoughts, comments and questions. RSS Feed


KeyDown and MessageBox don't mix well in Silverlight

I recently attempted to add keyboard support for deletion to a DataGrid control in a Silverlight application.

To help decide which event I should use—KeyUp or KeyDown—I decided to see how Microsoft Excel handled the Delete button. A quick test revealed that Excel deleted on KeyDown, and I figured if it was good enough for Excel, it was good enough for my app.

Therefore, I coded up the Delete button to use the KeyDown event, and (thoughtfully) added a confirm MessageBox dialog for the user asking if they actually wanted to delete the item. However, as soon as I started testing it, I noticed that it worked fine in Firefox but it would sometimes cause IE to crash and close.

After doing some debugging, I found that a serious-sounding exception (System.ExecutionEngineException) was getting thrown at the MessageBox.Show call (here it is recreated in a new project):

Visual Studio debugging with the ExecutionEngineException being thrown by the MessageBox.Show() method.

My first thought was that it was a bug with IE—mainly because of the violence of the crash. However, at lunch, I mentioned this to a colleague, and he mentioned that a crucial difference between KeyUp and KeyDown is that KeyDown repeatedly fires as long as the key is held down, whereas KeyUp does not. He suggested that the exception (and subsequent browser crash) might be caused by multiple events being fired.

A bit more research revealed that this was the issue. I was getting multiple events fired from the KeyDown, which were then trying to display more than one MessageBox at the same time. Since the MessageBox is modal, only one can be displayed at a time, and trying to display another caused the error.

Changing to the KeyUp event fixed the entire issue!

 
Posted by Keith Craig | 3 Comments | Trackback Url | Bookmark with:        
Tags:

Links to this Post

Comments

Thursday, 4 Dec 2008 06:59 by Morten
Did you consider opening the messagebox using Dispatcher.BeginInvoke ?

Friday, 5 Dec 2008 01:44 by Keith
No, I hadn't! Thanks for this tip! I tried this snippet of code in my event handler: Dispatcher.BeginInvoke(() => { MessageBox.Show("A key was pressed!"); }); And it worked great! By invoking my code onto the UI thread, it queues the code until the thread is not blocked, and then runs it without issue. My understanding is that it's the QUEUING that is important--the event handler is already running on the UI thread. Thanks! --Keith

Tuesday, 15 Sep 2009 05:27 by Ted
It worked perfectly for me....The article is clear enough...And I would like to add something more to this. "If you previously have been doing operations in the KeyDown event that could cause reentrancy into the Silverlight control, such as calling into the HtmlPage.Window.Alert function, this will no longer be supported." got it from http://forums.silverlight.net/forums/t/31371.aspx But couldnt understand clearly...But yours made it clear...

Name:
URL:
Email:
Comments:

CAPTCHA Image Validation