Monday 23 December 2019

c# - ArcGIS 10 add-in: ComboBox add-in component focus issue


Update 9/9/11: Here is a minimal example project that will reproduce the issue for me (VS 2008 solution): http://wfurl.com/09061bf


I have an ArcMap 10 add-in with a ComboBox class that I place on a toolbar. When I attempt to display a MessageBox after the user submits a value by typing in the ComboBox and pressing Enter, the ComboBox steals the keyboard focus from the MessageBox, so when the user tries to dismiss the MessageBox by pressing Enter again, the ComboBox's OnEnter event handler runs again instead of the MessageBox being closed.



Without any checks against this, you might end up with numerous MessageBox instances on top of one another with no way to dismiss them except by clicking OK on each one.


Attempts to work around this behavior have failed and include:



  1. Disabling the ComboBox before showing the MessageBox and re-enabling it afterwards. The enabled state doesn't change until after the MessageBox is closed and the focus issue still occurs. Employing Application.DoEvents has no effect.

  2. Setting a class-level boolean that tells the OnEnter handler to simply return when true (Set to True just before showing the MessageBox and False afterward.) The focus issue remains, meaning it takes 3 Enter keystrokes to dismiss the MessageBox, but at least the OnEnter code doesn't run again.

  3. Setting the MessageBox's parent window to the ArcMap application using the IWin32Window overload (actually this is necessary to get the MessageBox to show in the middle of the ArcMap window instead of on top of the ComboBox).

  4. Explicitly setting the MessageBox's MessageBoxOptions property to 0x1000 (MB_SYSTEMMODAL) or 0x2000 (MB_TASKMODAL)

  5. Using IApplication.StatusBar.set_Message() instead of MessageBox. The ComboBox's HintText message, even if not specified, or set to an empty string, instantly overrides anything I write in the set_Message main pane (0), so this method is essentially useless with Addin ComboBoxes.


Anyone have any other ideas as to what else I can try, or must I once again look at a WinAPI solution to deal with the ArcGIS framework's shortcomings?




Answer



In your code that you gave as an example. In my testing this worked for me.


new Thread(() =>
{
MessageBox.Show(String.Format("The value '{0}' is not an integer!", currentValue));
}).Start();

Edit To incorporate the great comments, and as Petr pointed out that this way may be dangerous here is the other way of doing this as well:


SynchronizationContext.Current.Post(_ => MessageBox.Show("Message"), null);


Thanks to Kirk and Petr for this!


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...