Przegląd Fokus

W WPF istnieją dwa główne pojęcia dotyczące fokusu: fokus klawiatury i fokus logiczny. Fokus klawiatury odnosi się do elementu, który odbiera wprowadzanie za pomocą klawiatury, a fokus logiczny odnosi się do elementu w zakresie koncentracji uwagi, który ma fokus. Te pojęcia zostały szczegółowo omówione w tym omówiniu. Zrozumienie różnicy 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, to Keyboard klasa, FocusManager klasa i klasy elementów podstawowych, takie jak UIElement i ContentElement. Aby uzyskać więcej informacji na temat elementów podstawowych, zobacz Omówienie elementów podstawowych.

Klasa Keyboard koncentruje się głównie na fokusie klawiatury FocusManager , a klasa dotyczy głównie fokusu logicznego, ale nie jest to bezwzględne rozróżnienie. Element, który ma fokus klawiatury również będzie mieć fokus logiczny, ale element, który ma fokus logiczny nie musi mieć fokus klawiatury. Jest to oczywiste, gdy używasz Keyboard klasy , aby ustawić element, który ma fokus klawiatury, ponieważ ustawia również logiczny fokus na elemencie.

Fokus klawiatury

Fokus klawiatury odnosi się do elementu, który obecnie odbiera dane wejściowe klawiatury. Na całym pulpicie może być tylko jeden element z fokusem klawiatury. W WPF element z fokusem klawiatury zostanie ustawiony IsKeyboardFocused na true. Właściwość statyczna klasy FocusedElementKeyboard pobiera element, który aktualnie ma fokus klawiatury.

Aby element uzyskał fokus klawiatury, Focusable właściwości i IsVisible elementów podstawowych muszą być ustawione na true. Niektóre klasy, takie jak klasa Panel bazowa, FocusableFocusablefalsetrue mają domyślnie ustawioną wartość . W związku z tym należy ustawić wartość na , 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 przez naciśnięcie klawisza Tab do elementu lub kliknięcie myszy na niektórych elementach. Fokus klawiatury można również uzyskać programowo przy użyciu Focus metody w klasie Keyboard . Metoda Focus próbuje nadać fokus klawiatury określonego elementu. Zwrócony element to element, który ma fokus klawiatury, który może być innym elementem niż żądane, jeśli stary lub nowy obiekt fokusu zablokuje żądanie.

W poniższym przykładzie użyto metody Focus , aby ustawić fokus klawiatury na .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 dowolny z jego wizualnych elementów podrzędnych ma fokus klawiatury.

Podczas ustawiania początkowego fokusu podczas uruchamiania aplikacji element, który ma otrzymać fokus, musi znajdować się w drzewie wizualnym początkowego okna załadowanego przez aplikację, a element FocusableIsVisible musi mieć wartość i ustawioną na true. Zalecane miejsce do ustawienia początkowego fokusu znajduje się w programie obsługi Loaded zdarzeń. Wywołanie Dispatcher zwrotne może być również używane przez wywołanie lub InvokeBeginInvoke.

Fokus logiczny

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

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

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

Element można zmienić w zakres koncentracji uwagi w języku Extensible Application Markup Language (XAML), ustawiając właściwość FocusManager dołączona na IsFocusScopetrue. W kodzie element można zmienić w zakres koncentracji uwagi, wywołując element SetIsFocusScope.

Poniższy przykład wprowadza obiekt w StackPanel zakres fokusu przez ustawienie dołączonej IsFocusScope właściwości.

<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 koncentracji uwagi dla określonego elementu.

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

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

Poniższy przykład ustawia element skoncentrowany na zakresie fokusu i pobiera element fokusu zakresu 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 implementację 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ą typu , KeyboardNavigationMode a możliwe wartości to Continue, Local, Contained, Cycle, Oncei None. Wartość domyślna to Continue, co oznacza, że element nie jest kontenerem nawigacji.

Poniższy przykład tworzy obiekt z Menu liczbą MenuItem obiektów . Właściwość TabNavigation dołączona jest ustawiona na wartość Cycle w obiekcie Menu. Gdy fokus zostanie zmieniony przy użyciu klawisza Tab Menuw elemencie , fokus zostanie zmieniony z każdego elementu, a po osiągnięciu ostatniego elementu fokus wró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 i MoveFocusPredictFocus.

MoveFocus zmienia fokus na następny element w aplikacji. A TraversalRequest służy do określania kierunku. Przekazane FocusNavigationDirection do określa MoveFocus różne kierunki fokusu można przenieść, takich jak First, Lasti UpDown.

W poniższym przykładzie użyto MoveFocus elementu , aby zmienić element ukierunkowany.

// 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 będzie miał fokus, gdyby fokus został zmieniony. Obecnie tylko , Up, i są Right obsługiwane przez program PredictFocus. LeftDown

Zdarzenia fokusu

Zdarzenia związane z fokusem klawiatury to PreviewGotKeyboardFocus, GotKeyboardFocus i PreviewLostKeyboardFocus. LostKeyboardFocus Zdarzenia są zdefiniowane jako zdarzenia dołączone Keyboard w klasie, ale są bardziej łatwo dostępne jako równoważne zdarzenia trasowane w klasach elementów podstawowych. Aby uzyskać więcej informacji na temat zdarzeń, zobacz Routed Events Overview (Omówienie zdarzeń tras).

GotKeyboardFocus jest wywoływana, gdy element uzyskuje fokus klawiatury. LostKeyboardFocus jest wywoływana, gdy element traci fokus klawiatury. Jeśli zdarzenie PreviewGotKeyboardFocus lub zdarzenie zostanie PreviewLostKeyboardFocusEvent obsłużone i Handled zostanie ustawione na truewartość , fokus nie zmieni się.

Poniższy przykład dołącza programy GotKeyboardFocus obsługi zdarzeń LostKeyboardFocus i do .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>

Gdy obiekt TextBox uzyskuje fokus klawiatury, Background właściwość obiektu jest TextBox 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

Gdy traci TextBox fokus klawiatury, Background 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 i GotFocusLostFocus. Te zdarzenia są definiowane jako FocusManager zdarzenia dołączone, ale nie FocusManager uwidacznia otok zdarzeń CLR. UIElement i ContentElement uwidaczniać te zdarzenia wygodniej.

Zobacz też