2012-03-30 6 views
0

Ich habe einen Suchbildschirm in meiner WPF-Anwendung. Der Bildschirm ist als UserControl in einem TabItem eines TabControl implementiert. Wenn der Benutzer zur Registerkarte Suchen wechselt, möchte ich, dass der Fokus in ein bestimmtes Feld wechselt. Ich stellte eine Frage here über, wie man herausfindet, wohin der Fokus ging. Ich weiß jetzt, wo es hingeht. Jetzt möchte ich herausfinden, warum es dort hingeht, damit ich es stoppen kann.Nun, da ich weiß, wo der Fokus liegt, wie finde ich heraus, warum es dort hingeht?

Beachten Sie, dass sich der Fokus spontan ändert und nichts mit Benutzeraktivitäten zu tun hat. Alles was der Benutzer getan hat, ist auf den Suchreiter im Hauptfenster zu klicken. Der Fokus soll auf diese eine bestimmte Textbox gehen; Dies geschieht in der UserControl Loaded Event-Handler. Und es geht zunächst zu dieser TextBox. Dann geht es aus irgendeinem Grund zur CheckBox.

Ich habe den TabIndex-Steuerelementen in meinem Formular Werte zugewiesen, mit denen der Benutzer interagieren kann. Die CheckBox befindet sich in TabIndex 1. Die betreffende TextBox befindet sich in TabIndex 9. Dies ist auch die einzige TextBox im Formular.

In der Vergangenheit wurde der Fokus auf die TextBox verschoben und blieb dort. Ohne es zu merken, änderte ich etwas, was dazu führte, dass der Fokus auf die CheckBox fiel. Ich weiß nicht, was ich geändert habe, außer dass es ungefähr zu der Zeit war, als ich die Telerik-Steuerbibliothek auf die neueste Version aktualisiert habe. Hier

ist die XAML für die gesamte Steuerung, minus einige Sachen, die würde keine Rolle spielen:

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

Danke für Ihre Hilfe

Tony

+0

Warum nicht den 'tabindex' so einrichten, dass das Textfeld zuerst angezeigt wird und dann jedes Element, auf das als nächstes zugegriffen werden soll, wenn die Tabulatortaste gedrückt wird, der Reihe nach folgt. Dies ermöglicht es einem Benutzer, Ihre Felder in einer logischen Reihenfolge auszufüllen, wenn Sie die Tabulatortaste drücken (im Gegensatz zu einer zufälligen Reihenfolge). Dies würde es auch so machen, dass du den Fokus im geladenen Ereignis nicht angeben musst (wie es zum ersten Tabindex gehen sollte) – jzworkman

+0

weißt du, das ist wahrscheinlich was passiert. Es sendet wahrscheinlich den Fokus auf den Tabindex mit der niedrigsten Nummer. Und es macht es, nachdem ich den Fokus auf die TextBox gelegt habe. Das Erstellen des TextBox-Tabindex 1 ist wahrscheinlich der richtige Weg. –

+0

Denken Sie daran, alle Tabindexes in die Reihenfolge zu ändern, in der der Benutzer sie ausfüllen soll (im Prinzip von links nach rechts und von oben nach unten). Wenn jemand mit Ihrem Formular interagiert (nur Tastatureingabe), haben Sie eine gute Benutzererfahrung. – jzworkman

Antwort

2

Gerade so, dass die Menschen Wer diese Frage später sieht, wusste, dass die Lösung darin bestand, die Felder auf dem Formular neu anzuordnen, so dass das Feld, auf das ich zuerst fokussieren wollte, das erste war Feld auf dem Formular. WPF legt den Fokus automatisch auf das Steuerelement mit dem niedrigsten TabIndex. Deshalb verlor meine Kontrolle den Fokus, nachdem ich sie in den Loaded-Event-Handler gelegt hatte.

Ich nehme an, dass, wenn ich keine TabIndex Feldsetzer im Xaml hätte, dass dies nie passiert wäre. Lebe und lerne.

+0

Es ist ein paar Monate später und während ich meinen Code nicht geändert habe, kommt es mir vor, dass das Problem, das ich hatte, war, wo ich den Fokus verlagerte. Ich habe es im 'Loaded' Event-Handler gemacht. Es könnte tatsächlich funktionieren, wenn ich es in eine andere Veranstaltung, wie das 'ContentRendered' Event, gesteckt hätte. Das könnte sich in der Zukunft lohnen. –