Silverlight's DatePicker / MessageBox Bug

Silverlight's DatePicker / MessageBox Bug

by JBrooks 26. December 2012 10:49

Silverlight has an annoying bug that has been around since at least 2008. If you have a MessageBox popup in a DatePicker’s SelectedDateChanged event, then the calendar will stay open and the SelectedDateChanged will fire for each time the mouse pointer hovers over a new date.  See HERE for someone asking for help on this and their sample code.

It happens because the DatePicker still flags the left mouse button as being down – the up button event was eaten by the message box.

I have a page where the user works on data for a given day, and if they change the date the page will be refreshed with the new day’s data.

My work flow was that if a user changed data for a day and then changed the date, I would prompt them with “Save Changes?” – Yes, No, Cancel.  If they selected Cancel I would just set the DatePicker’s date back. 

No matter what they selected the DatePicker’s calendar would remain down and the SelectedDataChanged would fire for each date that was hovered over.

I didn’t like any of the answers to this problem that I found.  So I changed the workflow so that the prompt to save changes wasn’t necessary anymore.  So this is the new workflow.

1. New page, you can change the date, refresh the data, or start editing the data.

image

2. The data was changed. Now changing the date is disabled until you make a choice between Save and Cancel. I like how this visibly tells the user that the data is dirty.

image

This is done by capturing the KeyUp event for the parent control that holds all of the editing controls. In my example it is a ContentControl but it could be a grid, etc.  Note that the control’s in the images above are outside of my ContentControl for the data.

private void ccData_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Left:
                case Key.Right:
                case Key.Down:
                case Key.Up:
                case Key.Tab:
                    break;

                default:
                    if (Status != PageStatus.Changed)
                    {
                        Status = PageStatus.Changed;
                    }
                    break;
            }
        }

When the Status property gets set the showing, hiding and disabling of controls takes place depending on the new value of PageStatus.

If the user clicks “Save” then the data is saved, the page is refreshed and they are back at step 1 with the date selection enabled. If they click “Cancel”, then I go to step 3.

3. They clicked “Cancel”.  Now they are free to change the date which pulls up another day’s data and throws away their changes (step 1).   Or they can continue editing, which puts them back to step 2.  Or they can click Refresh which will pull the old data from the database and the page will be back to step 1.

image

I like doing it this way so I don’t have to mess with the SelectedDateChanged event and I like the visual cues.

Tags:

Development | Silverlight