Bagikan melalui


Gambaran Umum Fokus

Dalam WPF ada dua konsep utama yang berkaitan dengan fokus: fokus keyboard dan fokus logis. Fokus keyboard mengacu pada elemen yang menerima input keyboard dan fokus logis mengacu pada elemen dalam cakupan fokus yang memiliki fokus. Konsep-konsep ini dibahas secara rinci dalam gambaran umum ini. Memahami perbedaan dalam konsep ini penting untuk membuat aplikasi kompleks yang memiliki beberapa wilayah di mana fokus dapat diperoleh.

Kelas utama yang berpartisipasi dalam manajemen fokus adalah Keyboard kelas, FocusManager kelas, dan kelas elemen dasar, seperti UIElement dan ContentElement. Untuk informasi selengkapnya tentang elemen dasar, lihat Gambaran Umum Elemen Dasar.

Kelas Keyboard ini terutama berkaitan dengan fokus keyboard dan FocusManager yang bersangkutan terutama dengan fokus logis, tetapi ini bukan perbedaan absolut. Elemen yang memiliki fokus keyboard juga akan memiliki fokus logis, tetapi elemen yang memiliki fokus logis tidak selalu memiliki fokus keyboard. Ini terlihat ketika Anda menggunakan Keyboard kelas untuk mengatur elemen yang memiliki fokus keyboard, untuk itu juga mengatur fokus logis pada elemen.

Fokus Keyboard

Fokus keyboard mengacu pada elemen yang saat ini menerima input keyboard. Hanya ada satu elemen pada seluruh desktop yang memiliki fokus keyboard. Di WPF, elemen yang memiliki fokus keyboard akan diatur IsKeyboardFocused ke true. Properti FocusedElement statis pada Keyboard kelas mendapatkan elemen yang saat ini memiliki fokus keyboard.

Agar elemen mendapatkan fokus keyboard, Focusable dan IsVisible properti pada elemen dasar harus diatur ke true. Beberapa kelas, seperti Panel kelas dasar, telah Focusable diatur ke false secara default; oleh karena itu, Anda harus mengatur Focusable ke true jika Anda ingin elemen seperti itu dapat mendapatkan fokus keyboard.

Fokus keyboard dapat diperoleh melalui interaksi pengguna dengan UI, seperti tab ke elemen atau mengklik mouse pada elemen tertentu. Fokus keyboard juga dapat diperoleh secara terprogram dengan menggunakan Focus metode pada Keyboard kelas . Metode ini Focus mencoba memberikan fokus keyboard elemen yang ditentukan. Elemen yang dikembalikan adalah elemen yang memiliki fokus keyboard, yang mungkin merupakan elemen yang berbeda dari yang diminta jika objek fokus lama atau baru memblokir permintaan.

Contoh berikut menggunakan Focus metode untuk mengatur fokus keyboard pada 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

Properti IsKeyboardFocused pada kelas elemen dasar mendapatkan nilai yang menunjukkan apakah elemen memiliki fokus keyboard. Properti IsKeyboardFocusWithin pada kelas elemen dasar mendapatkan nilai yang menunjukkan apakah elemen atau salah satu elemen anak visualnya memiliki fokus keyboard.

Saat mengatur fokus awal pada startup aplikasi, elemen untuk menerima fokus harus berada di pohon visual jendela awal yang dimuat oleh aplikasi, dan elemen harus memiliki Focusable dan IsVisible diatur ke true. Tempat yang disarankan untuk mengatur fokus awal ada di penanganan Loaded aktivitas. Panggilan Dispatcher balik juga dapat digunakan dengan memanggil Invoke atau BeginInvoke.

Fokus Logis

Fokus logis mengacu pada FocusManager.FocusedElement dalam cakupan fokus. Cakupan fokus adalah elemen yang melacak FocusedElement dalam cakupannya. Saat fokus keyboard meninggalkan cakupan fokus, elemen yang berfokus akan kehilangan fokus keyboard tetapi akan mempertahankan fokus logis. Saat fokus keyboard kembali ke cakupan fokus, elemen yang difokuskan akan mendapatkan fokus keyboard. Ini memungkinkan fokus keyboard diubah di antara beberapa cakupan fokus tetapi memastikan bahwa elemen yang difokuskan dalam cakupan fokus mendapatkan kembali fokus keyboard saat fokus kembali ke cakupan fokus.

Mungkin ada beberapa elemen yang memiliki fokus logis dalam aplikasi, tetapi mungkin hanya ada satu elemen yang memiliki fokus logis dalam cakupan fokus tertentu.

Elemen yang memiliki fokus keyboard memiliki fokus logis untuk cakupan fokus miliknya.

Elemen dapat diubah menjadi cakupan fokus dalam Extensible Application Markup Language (XAML) dengan mengatur FocusManager properti IsFocusScope terlampir ke true. Dalam kode, elemen dapat diubah menjadi cakupan fokus dengan memanggil SetIsFocusScope.

Contoh berikut menjadi StackPanel cakupan fokus dengan mengatur IsFocusScope properti terlampir.

<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 mengembalikan cakupan fokus untuk elemen yang ditentukan.

Kelas dalam WPF yang merupakan cakupan fokus secara default adalah Window, , MenuItemToolBar, dan ContextMenu.

GetFocusedElement mendapatkan elemen terfokus untuk cakupan fokus yang ditentukan. SetFocusedElement mengatur elemen yang difokuskan dalam cakupan fokus yang ditentukan. SetFocusedElement biasanya digunakan untuk mengatur elemen awal yang berfokus.

Contoh berikut mengatur elemen yang difokuskan pada cakupan fokus dan mendapatkan elemen terfokus dari cakupan fokus.

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

Navigasi Keyboard

Kelas KeyboardNavigation bertanggung jawab untuk menerapkan navigasi fokus keyboard default saat salah satu tombol navigasi ditekan. Tombol navigasi adalah: TAB, SHIFT+TAB, CTRL+TAB, CTRL+SHIFT+TAB, UPARROW, DOWNARROW, LEFTARROW, dan TOMBOL RIGHTARROW.

Perilaku navigasi kontainer navigasi dapat diubah dengan mengatur properti TabNavigationterlampir KeyboardNavigation , ControlTabNavigation, dan DirectionalNavigation. Properti ini berjenis KeyboardNavigationMode dan nilai yang mungkin adalah Continue, , Local, ContainedCycle, Once, dan None. Nilai defaultnya adalah Continue, yang berarti elemen bukan kontainer navigasi.

Contoh berikut membuat Menu dengan sejumlah MenuItem objek. Properti TabNavigation terlampir diatur ke Cycle pada Menu. Ketika fokus diubah menggunakan kunci tab dalam Menu, fokus akan berpindah dari setiap elemen dan ketika elemen terakhir tercapai fokus akan kembali ke elemen pertama.

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

API tambahan untuk bekerja dengan fokus adalah MoveFocus dan PredictFocus.

MoveFocus mengubah fokus ke elemen berikutnya dalam aplikasi. digunakan TraversalRequest untuk menentukan arah. Yang FocusNavigationDirection diteruskan untuk MoveFocus menentukan fokus petunjuk arah yang berbeda dapat dipindahkan, seperti First, , LastUp dan Down.

Contoh berikut menggunakan untuk mengubah elemen yang difokuskan MoveFocus .

// 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 mengembalikan objek yang akan menerima fokus jika fokus akan diubah. Saat ini, hanya Up, Down, Left, dan Right didukung oleh PredictFocus.

Peristiwa Fokus

Peristiwa yang terkait dengan fokus keyboard adalah PreviewGotKeyboardFocus, GotKeyboardFocus dan PreviewLostKeyboardFocus, LostKeyboardFocus. Peristiwa didefinisikan sebagai peristiwa terlampir pada Keyboard kelas, tetapi lebih mudah diakses sebagai peristiwa yang dirutekan yang setara pada kelas elemen dasar. Untuk informasi selengkapnya tentang peristiwa, lihat Gambaran Umum Peristiwa Yang Dirutekan.

GotKeyboardFocus dinaikkan ketika elemen mendapatkan fokus keyboard. LostKeyboardFocus dinaikkan ketika elemen kehilangan fokus keyboard. PreviewGotKeyboardFocus Jika peristiwa atau PreviewLostKeyboardFocusEvent peristiwa ditangani dan Handled diatur ke true, maka fokus tidak akan berubah.

Contoh berikut melampirkan GotKeyboardFocus dan LostKeyboardFocus penanganan aktivitas ke 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 Ketika mendapatkan fokus keyboard, Background properti diubah menjadi TextBoxLightBlue.

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 Ketika kehilangan fokus keyboard, Background properti dari TextBox diubah kembali menjadi putih.

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

Peristiwa yang terkait dengan fokus logis adalah GotFocus dan LostFocus. Peristiwa ini didefinisikan pada FocusManager sebagai peristiwa terlampir, tetapi FocusManager tidak mengekspos pembungkus peristiwa CLR. UIElement dan ContentElement mengekspos peristiwa ini dengan lebih nyaman.

Baca juga