Przegląd Fokus

W WPF istnieją dwa główne pojęcia, które odnoszą się do fokusu: fokus klawiatury i fokus logiczny. Fokus klawiatury odnosi się do elementu, który odbiera dane wejściowe klawiatury i fokus logiczny odnosi się do elementu w zakresie fokusu, który ma fokus. Te pojęcia zostały szczegółowo omówione w tym omówieniu. Zrozumienie różnic w tych pojęciach jest ważne w przypadku tworzenia złożonych aplikacji, które mają wiele regionów, w których można uzyskać fokus.

Główne klasy, które uczestniczą w zarządzaniu fokusem Keyboard , to klasa, FocusManager klasa i klasy podstawowe, takie jak UIElement i ContentElement. Aby uzyskać więcej informacji na temat elementów podstawowych, zobacz Omówienie elementów podstawowych.

Klasa Keyboard jest zaniepokojona przede wszystkim fokusem klawiatury i FocusManager dotyczy głównie logicznego skupienia, ale nie jest to absolutne rozróżnienie. Element, który ma fokus klawiatury, ma również fokus logiczny, ale element, który ma fokus logiczny, nie musi mieć fokusu klawiatury. Jest to oczywiste, gdy używasz Keyboard klasy do ustawiania elementu, który ma fokus klawiatury, dla niego ustawia również logiczny nacisk na element.

Fokus klawiatury

Fokus klawiatury odnosi się do elementu, który obecnie odbiera dane wejściowe klawiatury. Na całym pulpicie może znajdować się tylko jeden element, który ma fokus klawiatury. W WPF element, który ma fokus klawiatury, będzie miał IsKeyboardFocused ustawioną wartość true. Właściwość FocusedElement statyczna klasy Keyboard pobiera element, który obecnie ma fokus klawiatury.

Aby element mógł uzyskać fokus klawiatury, Focusable właściwości i IsVisible na elementach podstawowych muszą być ustawione na truewartość . Niektóre klasy, takie jak Panel klasa podstawowa, mają Focusable ustawioną false wartość domyślną, dlatego należy ustawić wartość Focusable na true , jeśli chcesz, aby taki element mógł uzyskać fokus klawiatury.

Fokus klawiatury można uzyskać za pośrednictwem interakcji użytkownika z interfejsem użytkownika, na przykład tabulacji do elementu lub kliknięcia myszy na niektórych elementach. Fokus klawiatury można również uzyskać programowo przy użyciu Focus metody w Keyboard klasie . Metoda Focus próbuje nadać określonemu elementowi fokus klawiatury. Zwrócony element to element, który ma fokus klawiatury, który może być innym elementem niż żądany, jeśli stary lub nowy obiekt fokusu blokuje żądanie.

W poniższym przykładzie użyto Focus metody , aby ustawić fokus klawiatury na obiekcie Button.

private void OnLoaded(object sender, RoutedEventArgs e)
{
    // Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton);
}
Private Sub OnLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Sets keyboard focus on the first Button in the sample.
    Keyboard.Focus(firstButton)
End Sub

Właściwość IsKeyboardFocused w klasach elementów podstawowych pobiera wartość wskazującą, czy element ma fokus klawiatury. Właściwość IsKeyboardFocusWithin w klasach elementów podstawowych pobiera wartość wskazującą, czy element lub którykolwiek z jego elementów podrzędnych wizualizacji ma fokus klawiatury.

Podczas ustawiania początkowego fokusu podczas uruchamiania aplikacji element do odbierania fokusu musi znajdować się w drzewie wizualnym okna początkowego załadowanego przez aplikację, a element musi mieć Focusable i IsVisible ustawić wartość true. Zalecane miejsce do ustawienia początkowego fokusu znajduje się w procedurze obsługi zdarzeń Loaded . Wywołanie Dispatcher zwrotne może być również używane przez wywołanie Invoke lub BeginInvoke.

Fokus logiczny

Fokus logiczny odnosi się do FocusManager.FocusedElement zakresu fokusu w zakresie koncentracji uwagi. Zakres fokusu to element, który śledzi FocusedElement zakres w zakresie. Gdy fokus klawiatury pozostawia zakres fokusu, element fokusu na klawiaturze utraci fokus, ale zachowa fokus logiczny. Gdy fokus klawiatury powróci do zakresu koncentracji uwagi, fokus fokusu zostanie zwrócony fokus klawiatury. Dzięki temu można zmienić fokus klawiatury między wieloma zakresami fokusu, ale gwarantuje, że element fokusu w zakresie fokusu odzyska fokus klawiatury, gdy fokus powróci do zakresu fokusu.

W aplikacji może istnieć wiele elementów, które mają fokus logiczny, ale może istnieć tylko jeden element, który ma fokus logiczny w określonym zakresie koncentracji uwagi.

Element, który ma fokus klawiatury, ma logiczny fokus dla zakresu fokusu, do którego należy.

Element można przekształcić w zakres fokusu w języku Extensible Application Markup Language (XAML), ustawiając dołączoną FocusManager właściwość IsFocusScope na truewartość . W kodzie element można przekształcić w zakres fokusu, wywołując metodę SetIsFocusScope.

W poniższym przykładzie element znajduje StackPanel się w zakresie koncentracji uwagi, ustawiając dołączoną IsFocusScope właściwość.

<StackPanel Name="focusScope1" 
            FocusManager.IsFocusScope="True"
            Height="200" Width="200">
  <Button Name="button1" Height="50" Width="50"/>
  <Button Name="button2" Height="50" Width="50"/>
</StackPanel>
StackPanel focuseScope2 = new StackPanel();
FocusManager.SetIsFocusScope(focuseScope2, true);
Dim focuseScope2 As New StackPanel()
FocusManager.SetIsFocusScope(focuseScope2, True)

GetFocusScope Zwraca zakres fokusu dla określonego elementu.

Klasy w WPF, które są zakresami fokusu domyślnie to Window, MenuItem, ToolBari ContextMenu.

GetFocusedElement pobiera element fokusu dla określonego zakresu fokusu. SetFocusedElement Ustawia element fokusu w określonym zakresie fokusu. SetFocusedElement jest zwykle używany do ustawiania początkowego elementu ukierunkowanego.

W poniższym przykładzie element fokusu jest ustawiany na zakres fokusu i pobiera element fokusu fokusu.

// Sets the focused element in focusScope1
// focusScope1 is a StackPanel.
FocusManager.SetFocusedElement(focusScope1, button2);

// Gets the focused element for focusScope 1
IInputElement focusedElement = FocusManager.GetFocusedElement(focusScope1);
' Sets the focused element in focusScope1
' focusScope1 is a StackPanel.
FocusManager.SetFocusedElement(focusScope1, button2)

' Gets the focused element for focusScope 1
Dim focusedElement As IInputElement = FocusManager.GetFocusedElement(focusScope1)

Nawigacja przy użyciu klawiatury

Klasa KeyboardNavigation jest odpowiedzialna za implementowanie domyślnej nawigacji fokusu klawiatury po naciśnięciu jednego z klawiszy nawigacji. Klucze nawigacji to: TAB, SHIFT+TAB, CTRL+TAB, CTRL+SHIFT+TAB, UPARROW, DOWNARROW, LEFTARROW i RIGHTARROW.

Zachowanie nawigacji kontenera nawigacji można zmienić, ustawiając dołączone KeyboardNavigation właściwości TabNavigation, ControlTabNavigationi DirectionalNavigation. Te właściwości są typuKeyboardNavigationMode, a możliwe wartości to Continue, , Local, ContainedCycle, Once, i None. Wartość domyślna to Continue, co oznacza, że element nie jest kontenerem nawigacji.

Poniższy przykład tworzy obiekt Menu z wieloma MenuItem obiektami. Dołączona TabNavigation właściwość jest ustawiona na Cycle wartość w obiekcie Menu. Gdy fokus zostanie zmieniony przy użyciu klawisza tabulacji w elemecie Menu, fokus zostanie przeniesiony z każdego elementu, a po osiągnięciu ostatniego elementu fokus powróci do pierwszego elementu.

<Menu KeyboardNavigation.TabNavigation="Cycle">
  <MenuItem Header="Menu Item 1" />
  <MenuItem Header="Menu Item 2" />
  <MenuItem Header="Menu Item 3" />
  <MenuItem Header="Menu Item 4" />
</Menu>
Menu navigationMenu = new Menu();
MenuItem item1 = new MenuItem();
MenuItem item2 = new MenuItem();
MenuItem item3 = new MenuItem();
MenuItem item4 = new MenuItem();

navigationMenu.Items.Add(item1);
navigationMenu.Items.Add(item2);
navigationMenu.Items.Add(item3);
navigationMenu.Items.Add(item4);

KeyboardNavigation.SetTabNavigation(navigationMenu,
    KeyboardNavigationMode.Cycle);
Dim navigationMenu As New Menu()
Dim item1 As New MenuItem()
Dim item2 As New MenuItem()
Dim item3 As New MenuItem()
Dim item4 As New MenuItem()

navigationMenu.Items.Add(item1)
navigationMenu.Items.Add(item2)
navigationMenu.Items.Add(item3)
navigationMenu.Items.Add(item4)

KeyboardNavigation.SetTabNavigation(navigationMenu, KeyboardNavigationMode.Cycle)

Dodatkowe interfejsy API do pracy z fokusem to MoveFocus i PredictFocus.

MoveFocus zmienia fokus na następny element w aplikacji. Element A TraversalRequest służy do określania kierunku. Przekazana FocusNavigationDirection wartość określa, że można przenosić MoveFocus różne kierunki koncentracji uwagi, takie jak First, LastUp i Down.

W poniższym przykładzie użyto MoveFocus metody w celu zmiany elementu ukierunkowanego.

// Creating a FocusNavigationDirection object and setting it to a
// local field that contains the direction selected.
FocusNavigationDirection focusDirection = _focusMoveValue;

// MoveFocus takes a TraveralReqest as its argument.
TraversalRequest request = new TraversalRequest(focusDirection);

// Gets the element with keyboard focus.
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;

// Change keyboard focus.
if (elementWithFocus != null)
{
    elementWithFocus.MoveFocus(request);
}
' Creating a FocusNavigationDirection object and setting it to a
' local field that contains the direction selected.
Dim focusDirection As FocusNavigationDirection = _focusMoveValue

' MoveFocus takes a TraveralReqest as its argument.
Dim request As New TraversalRequest(focusDirection)

' Gets the element with keyboard focus.
Dim elementWithFocus As UIElement = TryCast(Keyboard.FocusedElement, UIElement)

' Change keyboard focus.
If elementWithFocus IsNot Nothing Then
    elementWithFocus.MoveFocus(request)
End If

PredictFocus zwraca obiekt, który otrzyma fokus, gdyby fokus został zmieniony. Obecnie tylko Up, Down, Lefti Right są obsługiwane przez program PredictFocus.

Zdarzenia fokusu

Zdarzenia związane z fokusem klawiatury to PreviewGotKeyboardFocus, GotKeyboardFocus i PreviewLostKeyboardFocus, LostKeyboardFocus. Zdarzenia są definiowane jako dołączone zdarzenia w Keyboard klasie, ale są bardziej łatwo dostępne jako równoważne zdarzenia kierowane w klasach elementów bazowych. Aby uzyskać więcej informacji na temat zdarzeń, zobacz Omówienie zdarzeń trasowanych.

GotKeyboardFocus jest wywoływany, gdy element uzyskuje fokus klawiatury. LostKeyboardFocus jest zgłaszany, gdy element traci fokus klawiatury. PreviewGotKeyboardFocus Jeśli zdarzenie lub PreviewLostKeyboardFocusEvent zdarzenie jest obsługiwane i Handled jest ustawione na truewartość , fokus nie zmieni się.

Poniższy przykład dołącza GotKeyboardFocus programy obsługi zdarzeń i LostKeyboardFocus do programu TextBox.

<Border BorderBrush="Black" BorderThickness="1"
        Width="200" Height="100" Margin="5">
  <StackPanel>
    <Label HorizontalAlignment="Center" Content="Type Text In This TextBox" />
    <TextBox Width="175"
             Height="50" 
             Margin="5"
             TextWrapping="Wrap"
             HorizontalAlignment="Center"
             VerticalScrollBarVisibility="Auto"
             GotKeyboardFocus="TextBoxGotKeyboardFocus"
             LostKeyboardFocus="TextBoxLostKeyboardFocus"
             KeyDown="SourceTextKeyDown"/>
  </StackPanel>
</Border>

TextBox Po uzyskaniu fokusu Background klawiatury właściwość TextBox właściwości jest zmieniana na LightBlue.

private void TextBoxGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    TextBox source = e.Source as TextBox;

    if (source != null)
    {
        // Change the TextBox color when it obtains focus.
        source.Background = Brushes.LightBlue;

        // Clear the TextBox.
        source.Clear();
    }
}
Private Sub TextBoxGotKeyboardFocus(ByVal sender As Object, ByVal e As KeyboardFocusChangedEventArgs)
    Dim source As TextBox = TryCast(e.Source, TextBox)

    If source IsNot Nothing Then
        ' Change the TextBox color when it obtains focus.
        source.Background = Brushes.LightBlue

        ' Clear the TextBox.
        source.Clear()
    End If
End Sub

TextBox Po utracie fokusu Background klawiatury właściwość TextBox jest zmieniana z powrotem na biały.

private void TextBoxLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    TextBox source = e.Source as TextBox;

    if (source != null)
    {
        // Change the TextBox color when it loses focus.
        source.Background = Brushes.White;

        // Set the  hit counter back to zero and updates the display.
        this.ResetCounter();
    }
}
Private Sub TextBoxLostKeyboardFocus(ByVal sender As Object, ByVal e As KeyboardFocusChangedEventArgs)
    Dim source As TextBox = TryCast(e.Source, TextBox)

    If source IsNot Nothing Then
        ' Change the TextBox color when it loses focus.
        source.Background = Brushes.White

        ' Set the  hit counter back to zero and updates the display.
        Me.ResetCounter()
    End If
End Sub

Zdarzenia związane z fokusem logicznym to GotFocus i LostFocus. Te zdarzenia są definiowane FocusManager w zdarzeniach dołączonych, ale FocusManager nie uwidaczniają otoki zdarzeń CLR. UIElement i ContentElement uwidaczniaj te zdarzenia wygodniej.

Zobacz też