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 kelas Keyboard, kelas FocusManager, dan kelas elemen dasar, seperti UIElement dan ContentElement. Untuk informasi selengkapnya tentang elemen dasar, lihat Gambaran Umum Elemen Dasar .
Kelas Keyboard terutama berkaitan dengan fokus keyboard dan FocusManager terutama berkaitan dengan fokus logis, tetapi ini bukan perbedaan mutlak. 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 kelas Keyboard untuk mengatur elemen yang memiliki fokus keyboard, karena 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 memiliki IsKeyboardFocused diatur ke true
. Properti statis FocusedElement pada kelas Keyboard memperoleh elemen yang saat ini memiliki fokus keyboard.
Agar elemen mendapatkan fokus keyboard, Focusable dan properti IsVisible pada elemen dasar harus diatur ke true
. Beberapa kelas, seperti kelas dasar Panel, telah Focusable diatur ke false
secara default; oleh karena itu, Anda harus mengatur Focusable ke true
jika Anda ingin elemen seperti itu dapat memperoleh 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 metode Focus pada kelas Keyboard. Metode 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 metode Focus 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 memperoleh nilai yang mengindikasikan apakah elemen tersebut 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 direkomendasikan untuk mengatur fokus awal ada di penanganan aktivitas Loaded. Panggilan balik Dispatcher 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 properti terpasang FocusManagerIsFocusScope ke true
. Dalam kode, elemen dapat diubah menjadi cakupan fokus dengan memanggil SetIsFocusScope.
Contoh berikut membuat StackPanel ke dalam cakupan fokus dengan mengatur properti terlampir 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 mengembalikan cakupan fokus untuk elemen yang ditentukan.
Kelas dalam WPF yang merupakan cakupan fokus secara default adalah Window, MenuItem, ToolBar, 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 RIGHTARROW.
Perilaku navigasi kontainer navigasi dapat diubah dengan mengatur properti KeyboardNavigation terlampir TabNavigation, ControlTabNavigation, dan DirectionalNavigation. Properti-properti ini adalah berjenis KeyboardNavigationMode dan nilai yang mungkin adalah Continue, Local, Contained, Cycle, Once, dan None. Nilai default adalah Continue, yang berarti elemen bukan kontainer navigasi.
Contoh berikut membuat Menu dengan sejumlah objek MenuItem. Properti terlampir TabNavigation 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)
Menavigasi Fokus melalui Pemrograman
API tambahan untuk bekerja dengan fokus adalah MoveFocus dan PredictFocus.
MoveFocus mengubah fokus ke elemen berikutnya dalam aplikasi. TraversalRequest digunakan untuk menentukan arah. FocusNavigationDirection yang diteruskan ke MoveFocus menentukan arah berbeda tempat fokus dapat dipindahkan, seperti First, Last, Up, dan Down.
Contoh berikut menggunakan MoveFocus untuk mengubah elemen yang difokuskan.
// 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 yang didukung oleh PredictFocus.
Peristiwa Fokus
Peristiwa yang terkait dengan fokus keyboard adalah PreviewGotKeyboardFocus, GotKeyboardFocus dan PreviewLostKeyboardFocus, LostKeyboardFocus. Peristiwa didefinisikan sebagai peristiwa terlampir pada kelas Keyboard, 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 saat elemen mendapatkan fokus keyboard.
LostKeyboardFocus dinaikkan saat elemen kehilangan fokus keyboard. Jika peristiwa PreviewGotKeyboardFocus atau peristiwa PreviewLostKeyboardFocusEvent ditangani dan Handled diatur ke true
, maka fokus tidak akan berubah.
Contoh berikut melampirkan penanganan aktivitas GotKeyboardFocus dan LostKeyboardFocus 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>
Saat TextBox mendapatkan fokus pada keyboard, properti Background dari TextBox diubah menjadi 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
Ketika TextBox kehilangan fokus dari keyboard, properti Background pada 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.
Lihat juga
- FocusManager
- UIElement
- ContentElement
- Gambaran Umum Input
- Gambaran Umum Elemen Dasar
.NET Desktop feedback