Odağa Genel Bakış

WPFOdağıyla ilgili iki ana kavram vardır: klavye odağı ve mantıksal odak. Klavye odağı, klavye girişini alan ve mantıksal odak, odağı olan bir odak kapsamındaki öğeyi ifade eden öğe anlamına gelir. Bu kavramlar, bu genel bakışta ayrıntılı olarak ele alınmıştır. Bu kavramların farkını anlamak, odağın elde edilmesi gereken birden çok bölgeye sahip karmaşık uygulamalar oluşturmak için önemlidir.

Odak yönetimine katılan ana sınıflar, Keyboard ve gibi sınıf, FocusManager sınıf ve temel öğe sınıflarıdır UIElement ContentElement . Temel öğeler hakkında daha fazla bilgi için bkz. temel öğelere genel bakış.

KeyboardSınıf öncelikle klavye odağıyla ilgilidir ve FocusManager öncelikle mantıksal odak ile ilgilidir, ancak bu mutlak bir ayrım değildir. Klavye odağına sahip bir öğe ayrıca mantıksal odağa sahip olur, ancak mantıksal odağa sahip bir öğenin klavye odağı olması gerekmez. Bu, Keyboard klavye odağı olan öğeyi ayarlamak için sınıfını kullandığınızda görünür ve ayrıca öğesi için mantıksal odağı de belirler.

Klavye odağı

Klavye odağı, şu anda klavye girişi alan öğeyi ifade eder. Klavye odaklı bütün masaüstünde yalnızca bir öğe olabilir. WPF' De, klavye odağına sahip olan öğe IsKeyboardFocused olarak ayarlanır true . Sınıftaki static özelliği, FocusedElement Keyboard Şu anda klavye odağına sahip olan öğeyi alır.

Bir öğenin klavye odağını alması için, Focusable ve IsVisible temel öğelerdeki özellikler olarak ayarlanmalıdır true . Temel sınıf gibi bazı sınıflar Panel Focusable Varsayılan olarak olarak ayarlanmıştır false ; Bu nedenle, bu Focusable true tür bir öğenin klavye odağını alabilmesini istiyorsanız olarak ayarlamanız gerekir.

Klavye odağı, Kullanıcı arabirimi bir öğeye sekme veya belirli öğelerde fareyle tıklanması gibi ile Kullanıcı etkileşimi aracılığıyla elde edilebilir. Klavye odağı Ayrıca, sınıfındaki yöntemi kullanılarak programlı bir şekilde elde edilebilir Focus Keyboard . FocusYöntemi, belirtilen öğeye klavye odağı verme girişiminde bulunur. Döndürülen öğe,, eski veya yeni odak nesnesi isteği engelleyediyse, istenen farklı bir öğe olabilecek klavye odağına sahip olan öğedir.

Aşağıdaki örnek, Focus bir üzerinde klavye odağı ayarlamak için yöntemini kullanır 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

IsKeyboardFocusedTemel öğe sınıflarında özelliği, öğenin klavye odağına sahip olup olmadığını gösteren bir değer alır. IsKeyboardFocusWithinTemel öğe sınıflarında özelliği, öğenin veya görsel alt öğelerinden birinin klavye odağına sahip olup olmadığını gösteren bir değer alır.

Uygulama başlangıcında ilk odağı ayarlarken, odağı alacak olan öğe, uygulama tarafından yüklenen ilk pencerenin görsel ağacında olmalıdır ve öğesi, Focusable ve IsVisible olarak ayarlanmalıdır true . İlk odağı ayarlamak için önerilen yer Loaded olay işleyicisidir. DispatcherYa da çağırarak bir geri çağırma kullanılabilir Invoke BeginInvoke .

Mantıksal odak

Mantıksal odak, FocusManager.FocusedElement bir odak kapsamındaki öğesine başvurur. Odak kapsamı, kapsamı içinde takip eden bir öğedir FocusedElement . Klavye odağı bir odak kapsamından ayrıldığında, odaklanmış öğe klavye odağını kaybeder ancak mantıksal odağı korur. Klavye odağı odak kapsamına döndüğünde, odaklanmış öğe klavye odağını elde eder. Bu, klavye odağının birden çok odak kapsamı arasında değiştirilmesini sağlar, ancak odak kapsamındaki öğenin odak kapsamına dönüşmesini sağlayan odak kapsamı klavye odağı.

Bir uygulamada mantıksal odağa sahip birden fazla öğe olabilir, ancak yalnızca belirli bir odak kapsamında mantıksal odağa sahip bir öğe olabilir.

Klavye odağına sahip bir öğe, ait olduğu odak kapsamı için mantıksal odağa sahiptir.

Öğesi Extensible Application Markup Language (XAML) FocusManager ekli özelliği olarak ayarlanarak içindeki bir odak kapsamına açılabilir IsFocusScope true . Kodda, bir öğe çağırarak bir odak kapsamına açılabilir SetIsFocusScope .

Aşağıdaki örnek, StackPanel ekli özelliği ayarlayarak bir odak kapsamı içinde oluşturur IsFocusScope .

<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 Belirtilen öğe için odak kapsamını döndürür.

İçindeki,,, WPF ve varsayılan olarak odak kapsamları olan sınıflar Window MenuItem ToolBar ContextMenu .

GetFocusedElement belirtilen odak kapsamı için odaklanmış öğeyi alır. SetFocusedElement belirtilen odak kapsamındaki odaklanmış öğeyi ayarlar. SetFocusedElement genellikle ilk odaklanan öğeyi ayarlamak için kullanılır.

Aşağıdaki örnek, bir odak kapsamındaki odaklı öğeyi ayarlar ve odak kapsamının odaklanmış öğesini alır.

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

Klavye ile Gezinme

Bu KeyboardNavigation sınıf, gezinti tuşlarından birine basıldığında varsayılan klavye odağı gezintisini uygulamaktan sorumludur. Gezinti tuşları şunlardır: sekme, SHIFT + SEKME, CTRL + TAB, CTRL + SHIFT + TAB, UPOK, DOWNOK, LEFTARROW ve ıltarrow tuşları.

Gezinti kapsayıcısının gezinti davranışı, ve ekli özellikleri ayarlanarak değiştirilebilir KeyboardNavigation TabNavigation ControlTabNavigation DirectionalNavigation . Bu özellikler türündedir KeyboardNavigationMode ve olası değerler,,,, Continue ve ' dir Local Contained Cycle Once None . Varsayılan değer Continue , öğesinin bir gezinti kapsayıcısı olmadığı anlamına gelir.

Aşağıdaki örnek, bir Menu dizi nesne içeren bir oluşturur MenuItem . TabNavigationİliştirilmiş özelliği üzerinde olarak ayarlanır Cycle Menu . Odak, içindeki sekme tuşu kullanılarak değiştirildiğinde Menu , odak her öğeden taşınır ve son öğeye ulaşıldığında odak ilk öğeye döndürülür.

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

Odak ile çalışmak için ek API şunlardır MoveFocus PredictFocus .

MoveFocus değişiklikleri uygulamadaki Next öğesine odaklayın. TraversalRequestYönü belirtmek için kullanılır. FocusNavigationDirectionGeçirilen,, MoveFocus ve gibi farklı yönlerinin taşınabileceği farklı yönleri belirtir First Last Up Down .

Aşağıdaki örnek, MoveFocus odaklanmış öğeyi değiştirmek için kullanır.

// 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 odak değiştirilse, odağı alacak nesneyi döndürür. Şu anda, Up , Down Left ve Right tarafından desteklenir PredictFocus .

Odak olayları

Klavye odağıyla ilgili olaylar PreviewGotKeyboardFocus GotKeyboardFocus ve PreviewLostKeyboardFocus , LostKeyboardFocus . Olaylar, sınıf üzerinde ekli olaylar olarak tanımlanır Keyboard , ancak temel öğe sınıflarında eşdeğer yönlendirilmiş olaylar olarak daha kolay erişilebilir. Olaylar hakkında daha fazla bilgi için bkz. yönlendirilmiş olaylara genel bakış.

GotKeyboardFocus öğesi klavye odağını aldığında tetiklenir. LostKeyboardFocus öğe, klavye odağını kaybettiğinde tetiklenir. PreviewGotKeyboardFocusOlay veya PreviewLostKeyboardFocusEvent olay işlenirse ve Handled olarak ayarlanırsa true , odak değişmez.

Aşağıdaki örnek, GotKeyboardFocus ve LostKeyboardFocus olay işleyicilerini öğesine ekler 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>

TextBoxKlavye odağı aldığında, Background öğesinin özelliği TextBox olarak değiştirilir 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

TextBoxKlavye odağı kaybettiğinde, Background öğesinin özelliği TextBox beyaza geri değişir.

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

Mantıksal odak ile ilgili olaylar GotFocus ve LostFocus . Bu olaylar, FocusManager ekli olaylar olarak tanımlanmıştır, ancak FocusManager clr olay sarmalayıcıları sunmaz. UIElement ve ContentElement Bu olayları daha kolay bir şekilde kullanıma sunun.

Ayrıca bkz.