Question

I have a search screen in my WPF application. The screen is implemented as a UserControl in a TabItem of a TabControl. When the user switches to the Search tab, I want the focus to go into one particular field. I asked a question here about how to figure out where the focus was going to. I now know where it's going. Now I want to figure out why it's going there so I can stop it.

Note that the focus is changing spontaneously and has nothing to do with any user activity. All the user has done is click on the search tab in the main window. The focus is supposed to go to this one particular text box; this is done in the UserControl's Loaded event handler. And it does go to that TextBox initially. Then, for some reason, it goes to the CheckBox.

I have assigned values to the TabIndex controls on my form that the user can interact with. The CheckBox is at TabIndex 1. The TextBox in question is at TabIndex 9. This is also the only TextBox on the form.

In the past, the focus would move to the TextBox and stay there. Without realizing it, I changed something that causes the focus to go to the CheckBox. I don't know what it was that I changed, exept that it was at about the time I upgraded the Telerik controls library to the latest version.

Here is the Xaml for the whole control, minus some stuff that wouldn't matter:

<UserControl x:Class="CarSystem.CustomControls.Searcher"
         <!-- XML Namespaces removed for brevity -->
         Height="620"
         Loaded="UserControl_Loaded"
         Width="990">

<UserControl.Resources>
    <!--- Resource removed for brevity -->
</UserControl.Resources>

<Grid Background="{DynamicResource ContentBackground}"
      FocusManager.IsFocusScope="True"
      Name="LayoutRoot">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="110" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Grid Grid.Column="0"
          Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="0"
                  Grid.Row="0"
                  Header="Alarm Class:"
                  Margin="5,0">
            <Grid VerticalAlignment="Center">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="35" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <CheckBox Click="AllAlarmClasses_Click"
                          Content="ALL"
                          FontSize="14"
                          FontWeight="Bold"
                          Grid.Column="0"
                          Grid.Row="0"
                          HorizontalAlignment="Left"
                          Margin="5"
                          Name="AllAlarmClasses"
                          TabIndex="1"
                          VerticalAlignment="Center" />
                <Button Background="{DynamicResource ButtonBackground}"
                        Click="ExpandPicker_Click"
                        Content="Expand"
                        FontSize="14"
                        FontWeight="Bold"
                        Grid.Column="1"
                        Grid.Row="0"
                        Foreground="{DynamicResource ButtonForeground}"
                        Margin="5"
                        Name="ExpandAlarmClass"
                        TabIndex="2" />
                <ListBox BorderBrush="Black"
                         BorderThickness="1"
                         CheckBox.Click="AlarmClassPicker_Click"
                         ItemTemplate="{StaticResource CheckableChoice}"
                         FontSize="14"
                         FontWeight="Bold"
                         Grid.Column="0"
                         Grid.ColumnSpan="2"
                         Grid.Row="1"
                         Height="100"
                         ItemsSource="{Binding Path=AlarmClassChoices, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=TwoWay}"
                         Margin="5,0"
                         Name="AlarmClassPicker"
                         SelectionMode="Multiple"
                         TabIndex="3"
                         Visibility="Collapsed" />
            </Grid>
        </GroupBox>

        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="0"
                  Grid.Row="1"
                  Header="Source:"
                  Margin="5,0">
            <cs:TouchComboBox Background="{DynamicResource UnfocusedBackground}"
                              BorderBrush="{DynamicResource ControlBorder}"
                              FontSize="14"
                              FontWeight="Bold"
                              Foreground="{DynamicResource UnfocusedForeground}"
                              GridBackground="{DynamicResource ContentBackground}"
                              Height="50"
                              IsTabStop="True"
                              ItemsSource="{Binding Path=HotListChoices, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Mode=TwoWay}"
                              Margin="5,0"
                              x:Name="HotListPicker"
                              SelectionChanged="SourcePicker_SelectionChanged"
                              TabIndex="4"
                              TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                              VerticalAlignment="Top" />
        </GroupBox>
        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="1"
                  Grid.Row="0"
                  Header="Start Date:"
                  Margin="5,0">
            <telerik:RadDateTimePicker FontWeight="Bold"
                                       Height="35"
                                       Margin="5"
                                       Name="StartDatePicker"
                                       SelectionChanged="DateTimePicker_SelectionChanged"
                                       Style="{DynamicResource RadDateTimePickerControlTemplate1}"
                                       TabIndex="5"
                                       VerticalAlignment="Center" />
        </GroupBox>
        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="1"
                  Grid.Row="1"
                  Header="End Date:"
                  Margin="5,0">
            <telerik:RadDateTimePicker FontSize="14"
                                       FontWeight="Bold"
                                       Height="35"
                                       Margin="5"
                                       Name="EndDatePicker"
                                       SelectionChanged="DateTimePicker_SelectionChanged"
                                       Style="{DynamicResource RadDateTimePickerControlTemplate1}"
                                       TabIndex="6"
                                       VerticalAlignment="Center" />
        </GroupBox>

        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="2"
                  Grid.Row="0"
                  Header="State:"
                  Margin="5,0">
            <cs:TouchComboBox Background="{DynamicResource UnfocusedBackground}"
                              BorderBrush="{DynamicResource ControlBorder}"
                              DisplayMemberPath="Value"
                              FontSize="14"
                              FontWeight="Bold"
                              Foreground="{DynamicResource UnfocusedForeground}"
                              GridBackground="{DynamicResource ContentBackground}"
                              Height="50"
                              ItemsSource="{Binding Path=LocaleChoices, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
                              Margin="5"
                              x:Name="StatePicker"
                              SelectedValue="{Binding Path=LocaleCode}"
                              SelectedValuePath="Key"
                              SelectionChanged="StatePicker_SelectionChanged"
                              TabIndex="7"
                              TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                              VerticalAlignment="Center" />
        </GroupBox>
        <GroupBox BorderBrush="{DynamicResource ControlBorder}"
                  FontSize="16"
                  FontWeight="Bold"
                  Foreground="{DynamicResource TextForeground}"
                  Grid.Column="2"
                  Grid.Row="1"
                  Header="Plate:"
                  Margin="5,0">
            <Border BorderBrush="{DynamicResource ControlBorder}"
                    BorderThickness="1"
                    Height="35"
                    Margin="5"
                    VerticalAlignment="Center">
                <TextBox FontSize="14"
                         FontWeight="Bold"
                         GotFocus="PlateBox_GotFocus"
                         LostFocus="PlateBox_LostFocus"
                         Margin="-1"
                         MaxLength="25"
                         MaxLines="1"
                         Name="PlateBox"
                         TabIndex="8"
                         Text="{Binding Path=Plate, Mode=TwoWay}"
                         TextChanged="PlateBox_TextChanged"
                         ToolTip='Wildcards ("%", "_", "[", "]") can be used' />
            </Border>
        </GroupBox>
    </Grid>

    <TabControl Background="{DynamicResource TabBackground}"
                Grid.Row="1"
                Margin="0,20,0,5"
                Name="ResultTabs"
                TabIndex="9">

        <TabItem Background="{DynamicResource TabHeaderBackground}"
                 FontSize="16"
                 FontWeight="Bold"
                 Foreground="{DynamicResource TabHeaderForeground}"
                 Header="Hot List Entries:"
                 Name="HotListEntryTab">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <telerik:RadGridView AutoExpandGroups="True"
                                     AutoGenerateColumns="False"
                                     CanUserDeleteRows="False"
                                     CanUserFreezeColumns="False"
                                     CanUserInsertRows="False"
                                     CanUserResizeColumns="True"
                                     CanUserSortColumns="True"
                                     EnableColumnVirtualization="True"
                                     EnableRowVirtualization="True"
                                     FontSize="14"
                                     FontWeight="Bold"
                                     IsReadOnly="True"
                                     Name="HotListEntriesGrid"
                                     SelectionChanged="HotListEntriesGrid_SelectionChanged"
                                     SelectionUnit="FullRow"
                                     ScrollViewer.CanContentScroll="True"
                                     ScrollViewer.HorizontalScrollBarVisibility="Auto"
                                     ScrollViewer.VerticalScrollBarVisibility="Auto"
                                     TabIndex="10"
                                     ToolTip="Matching Hot List Entries">
                    <telerik:RadGridView.Columns>
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Plate,        Mode=OneWay}"
                                                    Header="Plate"
                                                    Width="*" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding LocaleCode, Mode=OneWay}"
                                                    Header="State"
                                                    Width="75" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding ListName,   Mode=OneWay}"
                                                    Header="Source"
                                                    Width="150" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding AlarmClass, Mode=OneWay}"
                                                    Header="Alarm Class"
                                                    Width="150" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Notes,     Mode=OneWay}"
                                                    Header="Notes"
                                                    Width="*" />
                    </telerik:RadGridView.Columns>
                </telerik:RadGridView>
                <cs:ProgressControl FontSize="14"
                                    FontWeight="Bold"
                                    Grid.Column="0"
                                    Grid.Row="1"
                                    Height="55"
                                    Margin="0,5"
                                    x:Name="HotListProgressCtrl"
                                    TabIndex="11"
                                    TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                                    Visibility="Collapsed" />
            </Grid>
        </TabItem>

        <TabItem Background="{DynamicResource TabHeaderBackground}"
                 FontSize="16"
                 FontWeight="Bold"
                 Foreground="{DynamicResource TabHeaderForeground}"
                 Header="Reads &amp; Alarms:"
                 IsSelected="True"
                 Name="ReadsTabItem">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <telerik:RadGridView AutoExpandGroups="True"
                                     AutoGenerateColumns="False"
                                     CanUserDeleteRows="False"
                                     CanUserFreezeColumns="False"
                                     CanUserInsertRows="False"
                                     CanUserResizeColumns="True"
                                     CanUserSortColumns="True"
                                     EnableColumnVirtualization="True"
                                     EnableRowVirtualization="True"
                                     FontSize="14"
                                     FontWeight="Bold"
                                     IsReadOnly="True"
                                     Name="ReadsGrid"
                                     RowDetailsTemplate="{StaticResource ReadRowDetailsTemplate}"
                                     RowStyleSelector="{StaticResource StyleSelector}"
                                     SelectionChanged="ReadsGrid_SelectionChanged"
                                     SelectionUnit="FullRow"
                                     ScrollViewer.CanContentScroll="True"
                                     ScrollViewer.HorizontalScrollBarVisibility="Auto"
                                     ScrollViewer.VerticalScrollBarVisibility="Auto"
                                     ShowGroupFooters="True"
                                     TabIndex="12"
                                     ToolTip="Matching Reads">
                    <telerik:RadGridView.Columns>
                        <cs:CustomGridViewToggleRowDetailsColumn IsEnabled="False"
                                                                 IsFilterable="False"
                                                                 IsGroupable="False"
                                                                 ToggleButtonVisibility="{Binding Path=HasAlarms, Converter={StaticResource BoolToVisibility}}" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Plate,       Mode=OneWay}"
                                                    Header="Plate"
                                                    Width="*" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding State,       Mode=OneWay}"
                                                    Header="State"
                                                    Width="75" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding TimeStamp,  Mode=OneWay, Converter={StaticResource DateConverter}}"
                                                    Header="Date &amp; Time"
                                                    Width="150" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Latitude, Converter={StaticResource CoordConverter}, ConverterParameter=NS}"
                                                    Header="Latitude"
                                                    Width="150" />
                        <telerik:GridViewDataColumn DataMemberBinding="{Binding Longitude, Converter={StaticResource CoordConverter}, ConverterParameter=EW}"
                                                    Header="Longitude"
                                                    Width="150" />
                    </telerik:RadGridView.Columns>
                </telerik:RadGridView>
                <cs:ProgressControl FontSize="14"
                                    FontWeight="Bold"
                                    Grid.Row="1"
                                    Height="55"
                                    Margin="0,5"
                                    x:Name="ProgressCtrl"
                                    TabIndex="13"
                                    TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                                    Visibility="Collapsed" />
            </Grid>
        </TabItem>
    </TabControl>

    <GridSplitter Background="{DynamicResource SeparatorColor}"
                  Grid.Row="1"
                  Height="10"
                  HorizontalAlignment="Stretch"
                  Margin="0,5"
                  VerticalAlignment="Top" />

    <Grid Grid.Column="1"
          Grid.RowSpan="2">
        <Grid.RowDefinitions>
            <RowDefinition Height="55" />
            <RowDefinition Height="55" />
            <RowDefinition Height="55" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
            <RowDefinition Height="55" />
            <RowDefinition Height="55" />
        </Grid.RowDefinitions>
        <Button Background="{DynamicResource ButtonBackground}"
                Click="SearchButton_Click"
                Content="Search"
                FontSize="16"
                FontWeight="Bold"
                Foreground="{DynamicResource ButtonForeground}"
                Grid.Row="0"
                IsDefault="True"
                Margin="5"
                Name="SearchButton"
                TabIndex="14" />
        <Button Background="{DynamicResource ButtonBackground}"
                Click="ClearButton_Click"
                Content="Clear"
                FontSize="16"
                FontWeight="Bold"
                Foreground="{DynamicResource ButtonForeground}"
                Grid.Row="1"
                Margin="5"
                Name="ClearButton"
                TabIndex="15" />
        <Button Background="{DynamicResource ButtonBackground}"
                Click="SaveCriteriaButton_Click"
                FontSize="16"
                FontWeight="Bold"
                Grid.Row="2"
                Foreground="{DynamicResource ButtonForeground}"
                Margin="5"
                Name="SaveCriteriaButton"
                TabIndex="16"
                Visibility="Visible">
            <Button.Content>
                <TextBlock Text="Save Report"
                           TextAlignment="Center"
                           TextWrapping="Wrap" />
            </Button.Content>
        </Button>
        <TextBlock FontSize="14"
                   FontWeight="Bold"
                   Foreground="{DynamicResource TextForeground}"
                   Grid.Row="4"
                   Margin="5"
                   Text="Number of Matches:"
                   TextAlignment="Center"
                   TextWrapping="Wrap" />
        <TextBlock FontSize="14"
                   FontWeight="Bold"
                   Foreground="{DynamicResource TextForeground}"
                   Grid.Row="5"
                   Margin="5"
                   Text="Hot List Entries:"
                   TextAlignment="Center"
                   TextWrapping="Wrap" />
        <TextBlock FontSize="14"
                   FontWeight="Bold"
                   Foreground="{DynamicResource TextForeground}"
                   Grid.Row="6"
                   Margin="5,0,5,10"
                   Text="{Binding Converter={StaticResource LongConverter}, ConverterParameter='#,##0', Path=NoHotListEntries, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                   TextAlignment="Center"
                   TextWrapping="Wrap" />
        <TextBlock FontSize="14"
                   FontWeight="Bold"
                   Foreground="{DynamicResource TextForeground}"
                   Grid.Row="7"
                   Margin="5"
                   Text="Reads:"
                   TextAlignment="Center"
                   TextWrapping="Wrap" />
        <TextBlock FontSize="14"
                   FontWeight="Bold"
                   Foreground="{DynamicResource TextForeground}"
                   Grid.Row="8"
                   Margin="5,0,5,10"
                   Text="{Binding Converter={StaticResource LongConverter}, ConverterParameter='#,##0', Path=NoReads, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                   TextAlignment="Center"
                   TextWrapping="Wrap" />
        <Button Background="{DynamicResource ButtonBackground}"
                Click="ExportButton_Click"
                Content="Export"
                FontSize="16"
                FontWeight="Bold"
                Foreground="{DynamicResource ButtonForeground}"
                Grid.Row="10"
                Margin="5"
                Name="ExportButton"
                TabIndex="17" />
        <Button Background="{DynamicResource ButtonBackground}"
                Click="CloseButtonClicked"
                Content="Close"
                FontSize="20"
                FontWeight="Bold"
                Foreground="{DynamicResource ButtonForeground}"
                Grid.Row="11"
                HorizontalAlignment="Right"
                Margin="5"
                Name="CloseButton"
                TabIndex="18"
                Width="100" />
    </Grid>

    <Canvas Grid.Column="0"
            Grid.ColumnSpan="2"
            Grid.Row="0"
            Grid.RowSpan="4"
            Name="KeyboardPopupCanvas">
        <cs:KeyboardPopup x:Name="KeyboardPopup"
                          TimeOfDayMode="{Binding Path=TimeOfDayMode, RelativeSource={RelativeSource AncestorType={x:Type cs:Searcher}}}"
                          Title="Keyboard"
                          Visibility="Collapsed" />
    </Canvas>

</Grid>

Thanks for your help

Tony

Was it helpful?

Solution

Just so that people who view this question later will know, the solution I went with was to rearrange the fields on the form so that the field I wanted to have the focus initially was the first field on the form. WPF automatically gives the focus to the control with the lowest TabIndex. Which is why my control was losing the focus after I put it there in the Loaded event handler.

I suppose that if I didn't have any TabIndex field setters in the Xaml that this would never have happened. Live and learn.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top