Теперь, когда я знаю, куда направлен фокус, как я могу выяснить, почему он там собирается? - PullRequest
0 голосов
/ 30 марта 2012

У меня есть экран поиска в моем приложении WPF. Экран реализован как пользовательский элемент управления в элементе TabIont элемента TabControl. Когда пользователь переключается на вкладку «Поиск», я хочу, чтобы фокус переместился в одно конкретное поле. Я задал вопрос здесь о том, как выяснить, куда направлен фокус. Теперь я знаю, куда это идет. Теперь я хочу выяснить, почему это происходит, чтобы я мог это остановить.

Обратите внимание, что фокус меняется самопроизвольно и не имеет никакого отношения к какой-либо активности пользователя. Все, что сделал пользователь, это нажал на вкладку поиска в главном окне. Предполагается, что основное внимание будет уделено этому конкретному текстовому полю; это делается в обработчике событий Loaded UserControl. И это действительно идет к этому TextBox изначально. Затем по какой-то причине он переходит к CheckBox.

Я назначил значения элементам управления TabIndex в моей форме, с которыми пользователь может взаимодействовать. CheckBox находится в TabIndex 1. Соответствующий TextBox находится в TabIndex 9. Это также единственный TextBox в форме.

Раньше фокус переместился на TextBox и оставался там. Не осознавая этого, я изменил что-то, что заставляет фокус перейти на CheckBox. Я не знаю, что именно я изменил, за исключением того времени, когда я обновил библиотеку элементов управления Telerik до последней версии.

Вот Xaml для всего элемента управления, за исключением некоторых вещей, которые не имеют значения:

<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>

Спасибо за вашу помощь

Tony

1 Ответ

2 голосов
/ 30 марта 2012

Чтобы люди, которые позже увидят этот вопрос, знали, я выбрал решение переставить поля формы так, чтобы поле, которое я хотел сфокусировать, было первым полем формы. WPF автоматически придает фокус элементу управления с самым низким TabIndex. Вот почему мой элемент управления терял фокус после того, как поместил его в обработчик событий Loaded.

Полагаю, что если бы в Xaml не было никаких установщиков полей TabIndex, этого бы никогда не произошло. Живи и учись.

...