Tag Archives: Dispatcher.CheckAccess

Help! My app is minimized and my dialog won’t pop up!

Recently, one of our clients complained that they weren’t “adequately” notified when some of their trading orders stopped. The big problem with this is that they only noticed the Idle orders near the end of the trading day.  Apparently, they didn’t see the awesome “Errors and Exceptions” dialog that is supposed to pop up anytime the server throws an exception on an order.

Don’t Minimize Me Bro!

After I let the trader vent his frustration, I tried to do some detective work and recreate the situation and figure out what happened. Sure enough the user found a use case I hadn’t considered before. To save screen real estate he had minimized the app and left it on auto-pilot.

The code that responded to the error messages and displayed the Errors Dialog worked correctly but will not show a dialog if the parent window is minimized.

Who’s Your Daddy?

Some searching of the interwebs suggested that I set the dialog windows Topmost = “True” but that wasn’t enough to get the job done.  I figured that it probably had to do with the fact that I was assigning the ErrorDialog.Owner to the MainWindow and since the MainWindow was minimized it must be forcing all its “children” to be minimized as well.

The Code 🙂

I severed the relationship between the two windows and then I added an “else” so that if the user had minimized the Error Dialog instead of closing it, it would still pop up without creating additional Dialogs.

        public void ViewErrorListManager(object param)
        {            
            // Can only call from Main Dispatcher so check before proceeding and switch if necessary
            // Note the best way to check if the UI thread is active is to use .CheckAccess()
            // Dispatcher.CurrentDispatcher.Thread == Thread.CurrentThread is NOT 
            // a good way to check for UI thread. This is becasue Dispatcher.CurrentDispatcher will
            // create a new Dispatcher associated with the current Thread. This is not what you want!
            if (Application.Current.Dispatcher.CheckAccess())
            {
                // check if window is already open
                if (!Application.Current.Windows.OfType<SystemAlertDialog>().Any())
                {
                    SystemAlertDialog dlg = new SystemAlertDialog();
                    dlg.DataContext = _alertVM;
                    dlg.Show();
                }
                else
                {
                    SystemAlertDialog dlg = Application.Current.Windows.OfType<SystemAlertDialog>().First();
                    if (dlg != null)
                    {
                        dlg.WindowState = WindowState.Normal;
                        dlg.Focus();
                    }
                }
            }
            else
            {
                // Invoke the call from the "Main Dispatcher"
                // Note this.Dispatcher is not valid on a non Window class
                // Note Dispatcher.CurrentDispatcher.BeginInvoke() will also not work 
                // because only the main UI thread has a message queue and pump
                Application.Current.Dispatcher.BeginInvoke(new Action(() => ViewErrorListManager(new object())));
            }
        }

Yes!