Maintaining tab order when controls are disabled and enabled again at unpredictable times

Viewed 2036

So let me warn you; I am asking for a way to make a total hack work somewhat better. I admit that it is a hack and am certainly open to different takes on the problem as a whole. That said, I need to get this in soon if I want to make code cutoff and we have a somewhat aggressive release date.

As such, I will not be able to make large changes immediately, but I can easily do so for the first patch to this software. So, short and long term solutions are welcome, but a short term solution (if possible) is preferable.

Ok, so here is the issue; I have an application that send commands to a robotic hardware device. After a command is sent that requires a wait (for example, a physical motion that takes an unknown amount of time) the UI goes into a "Busy State". When this occurs all controls that would issue another blocking command are disabled as the machine cannot process them.

When the UI comes out of a busy state all controls are once again enabled, but the tab order is not maintained for obvious reasons. This makes tabbing through input areas impossible and, seeing as I myself use the keyboard almost exclusively, is not acceptable. My current scheme to "solve" this problem is to:

  1. At startup, register to the GotFocus event for each control of interest in the application. This is made difficult due to the fact that this is a WPF MVVM app and also because some controls are created dynamically. Nevertheless, I can search the visual and/or logical trees and get by...
  2. In the GotFocus event, save a reference to the control.
  3. When we exit a busy state, attempt to set focus to the saved control.

This works... kinda sorta. The issue at hand (as I can think of more fail scenarios...) is that this logic will blow away a context menu if it was open and another. Consider:

  1. Focus is in a text area.
  2. User right clicks another control. This control does not get focus (even if I try to set it in a mouse handler).
  3. System goes into a busy state as the right click performed a move.
  4. When the busy state ends, text area is given focus and the context menu closes.

(Now I realize that you may say that performing a move on a right click and also displaying a context menu is a bad idea, but the context menu commands are non-blocking, enabled, and it has a domain specific use that is convenient.)

So there it is. I can't even get focus in a right click, and setting focus to the menu itself doesn't work either. I'm just curious if anyone has a better scheme for something like this. I realize it is awkward and a very narrow circumstance. Thanks for any help you can offer in advance, I will be playing around with this some more...

5 Answers

Workaround for this :-Instead of disabling the control You should use XamBusyIndicator as a parent of that control and set the property for IsBusy. If IsBusy is true it will disable the child control and also TabIndex property will run in a sensible manner. For example:-

<igComboEditor:XamBusyIndicator IsBusy="{Binding IsBusy}" Height="22">
                                <igComboEditor:XamBusyIndicator.Animation>
                                    <igComboEditor:CustomBusyAnimation DataTemplate="{StaticResource CustomBusyIndicatorTemplate}" />
                                </igComboEditor:XamBusyIndicator.Animation>
                                <igComboEditor:XamComboEditor Width="125"  VerticalAlignment="Bottom" Style="{StaticResource XamComboEditorStyle}"
                                                          ItemsSource="{Binding DataList}" IsEditable="False" 
                                                          SelectedItem="{Binding SelectedData}">

                            </igComboEditor:XamComboEditor>
                            </igComboEditor:XamBusyIndicator>
Related