Every time I run the app, and select the second tab, ShowDialog() throws an InvalidOperationException, with the message 'Dispatcher processing has been suspended, but messages are still being processed.' (Full stack trace at bottom of post).

Also note that Window.ShowDialog() and MessageBox.Show() cause the same error.

What is causing this? Maybe I am not supposed to call anything that *could* affect dependency properties from a dependency property related event handler (I noticed that IsVisibleChanged is aDependencyPropertyChangedEventHandler) however I can't seem to find any documentation about this.

I also thought this could be caused by internal nested message processing / use of PushFrame to create a message loop for the dialog. Based on the idea that this could be caused by a threading problem, I changed the code as below, which runs without any problems (Is this a valid workaround?):

Answers

This is done on purpose to prevent reentrancy bugs caused by weirdness resulting from altering the visual tree while such an event (which itself has been triggered by the visual tree altering) is firing. If you really must confirm something when the Visible state of a UI element changes (I can't think of a single good reason why you would) delaying with Dispatcher.BeginInvoke is probably the right thing to do.

All replies

This is done on purpose to prevent reentrancy bugs caused by weirdness resulting from altering the visual tree while such an event (which itself has been triggered by the visual tree altering) is firing. If you really must confirm something when the Visible state of a UI element changes (I can't think of a single good reason why you would) delaying with Dispatcher.BeginInvoke is probably the right thing to do.

Just for completeness the reason for using IsVisibleChanged is because we need to perform a (deferred) UI update when a certain tab becomes visible, and it just so happens that because the tab is used to trigger an asynchronous process, that process may have completed in the meantime, so we may need to prompt the user to save the results of the process on returning to that tab. In hindsight I may be able to get the same functionality using Loaded and checking IsVisible.