Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A WPF-ben két fő fogalma van a fókusznak: a billentyűzetfókusz és a logikai fókusz. A billentyűzetfókusz arra az elemre vonatkozik, amely a billentyűzetbemenetet fogadja, a logikai fókusz pedig a fókuszt tartalmazó fókusz hatókörének elemére vonatkozik. Ezeket a fogalmakat részletesen tárgyaljuk ebben az áttekintésben. Ezeknek a fogalmaknak a különbségének megértése fontos az olyan összetett alkalmazások létrehozásához, amelyek több régióval rendelkeznek, ahol a fókusz elérhető.
A fókuszkezelésben részt vevő fő osztályok a Keyboard osztály, a FocusManager osztály és az alapelemosztályok, például UIElement és ContentElement. További információ az alapelemekről: Alapelemek áttekintése.
A Keyboard osztály elsősorban a billentyűzetfókuszsal foglalkozik, a FocusManager pedig elsősorban a logikai fókuszsal foglalkozik, de ez nem abszolút különbség. A billentyűzetfókuszú elemek is logikai fókuszban lesznek, de a logikai fókuszú elemek nem feltétlenül rendelkeznek billentyűzetfókusszal. Ez akkor válik nyilvánvalóvá, ha a Keyboard osztályt használja a billentyűzetfókuszú elem beállításához, mert az logikai fókuszt is beállít az elemre.
Billentyűzetfókusz
A billentyűzetfókusz arra az elemre vonatkozik, amely jelenleg billentyűzetbemenetet fogad. A billentyűzetfókuszt tartalmazó asztalon csak egy elem lehet. A WPF-ben a billentyűzetfókuszú elem IsKeyboardFocusedtruelesz beállítva. A FocusedElement osztály statikus tulajdonsága Keyboard az aktuális billentyűzetfókuszú elemet kapja.
Ahhoz, hogy egy elem megkapja a billentyűzetfókuszt, az alapelemek Focusable és IsVisible tulajdonságait truekell beállítani. Egyes osztályok, például az Panel alaposztály, alapértelmezés szerint a Focusablefalse-re van állítva; ezért Focusable kell beállítania true, ha azt szeretné, hogy egy ilyen elem képes legyen a fókusz elérésére a billentyűzettel.
A billentyűzetfókusz a felhasználói felülettel való felhasználói interakcióval érhető el, például egy elemhez való lapozással vagy bizonyos elemeken az egérre való kattintással. A billentyűzetfókusz programozott módon is elérhető a Focus osztály Keyboard metódusával. A Focus metódus megpróbálja fókuszba helyezni a megadott elem billentyűzetét. A visszaadott elem a billentyűzetfókuszú elem, amely a kéréstől eltérő elem lehet, ha a régi vagy az új fókuszobjektum blokkolja a kérést.
Az alábbi példa a Focus metódust használja egy Buttonbillentyűzetfókuszának beállításához.
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
Az alapelemosztályok IsKeyboardFocused tulajdonsága egy értéket kap, amely jelzi, hogy az elem rendelkezik-e billentyűzetfókuszsal. Az alapelemosztályok IsKeyboardFocusWithin tulajdonsága olyan értéket kap, amely jelzi, hogy az elem vagy annak bármely vizuális gyermekeleme rendelkezik-e billentyűzetfókuszsal.
Amikor az alkalmazás indításakor beállítjuk a kezdeti fókuszt, a fókuszt kapó elemnek az alkalmazás által betöltött kezdeti ablak vizuális fájában kell lennie, és az elemnél a Focusable és IsVisible értékének true-nek kell lennie. A kezdeti fókusz beállításának ajánlott helye az Loaded eseménykezelőben található. A Dispatcher visszahívás Invoke vagy BeginInvokehívásával is használható.
Logikai fókusz
A logikai fókusz a fókusz hatókörében a FocusManager.FocusedElement-ra utal. A fókusz tartomány olyan elem, amely nyomon követi a saját hatókörén belüli FocusedElement-t. Ha a billentyűzetfókusz elhagyja a fókusz hatókörét, a szűrt elem elveszíti a billentyűzetfókuszt, de megtartja a logikai fókuszt. Amikor a billentyűzetfókusz visszakerül a fókusz hatókörébe, a szűrt elem megkapja a billentyűzetfókuszt. Ez lehetővé teszi, hogy a billentyűzet fókusza több fókusztartomány között megváltozzon, de biztosítja, hogy a fókusz hatókörének szűrt eleme visszanyerje a billentyűzet fókuszát, amikor a fókusz visszakerül a fókusz hatókörébe.
Több olyan elem is lehet, amelynek logikai fókusza van egy alkalmazásban, de lehet, hogy csak egy elem rendelkezik logikai fókuszsal egy adott fókusztartományban.
A billentyűzetfókuszú elem logikai fókuszt használ arra a fókusztartományra, amelyhez tartozik.
Egy elem az Extensible Application Markup Language (XAML) alkalmazásban fókusz körré alakítható, ha a FocusManager csatolt tulajdonságot IsFocusScopetrueértékre állítják. A kódban az elemek fókusztartománysá alakíthatók SetIsFocusScopemeghívásával.
Az alábbi példa a StackPanel elemet fókuszterületté alakítja a IsFocusScope csatolt tulajdonság beállításával.
<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 a megadott elem fókusztartományát adja vissza.
A WPF-ben alapértelmezés szerint fókuszhatókörként szolgáló osztályok Window, MenuItem, ToolBarés ContextMenu.
GetFocusedElement lekéri a megadott fókusztartomány szűrt elemét. SetFocusedElement beállítja a szűrt elemet a megadott fókusztartományban. SetFocusedElement általában a kezdeti fókuszált elem beállítására használnak.
Az alábbi példa beállítja a fókusz hatókörének szűrt elemét, és lekéri a fókusz hatókörének szűrt elemét.
// 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)
Billentyűzet-navigáció
Az KeyboardNavigation osztály felelős az alapértelmezett billentyűzetfókusz-navigáció megvalósításáért, amikor az egyik navigációs gombot lenyomja. A navigációs kulcsok a következők: TAB, SHIFT+TAB, CTRL+TAB, CTRL+SHIFT+TAB, UPARROW, DOWNARROW, LEFTARROW és RIGHTARROW billentyűk.
A navigációs tárolók navigációs viselkedése a csatolt KeyboardNavigation tulajdonságok TabNavigation, ControlTabNavigationés DirectionalNavigationbeállításával módosítható. Ezek a tulajdonságok KeyboardNavigationMode típusúak, és a lehetséges értékek a következők: Continue, Local, Contained, Cycle, Onceés None. Az alapértelmezett érték Continue, ami azt jelenti, hogy az elem nem navigációs tároló.
A következő példa egy Menu-t hoz létre több MenuItem objektummal. A TabNavigation csatolt tulajdonság a Cycle-n Menu-re van állítva. Ha a fókusz a Menubelüli tabulátorbillentyűvel változik, a fókusz minden elemről elmozdul, és az utolsó elem elérésekor a fókusz visszakerül az első elemre.
<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)
Fókusz programozott navigálása
A fókusz kezeléséhez további API-k állnak rendelkezésre: MoveFocus és PredictFocus.
MoveFocus az alkalmazás következő elemére helyezi a fókuszt. A TraversalRequest az irány megadására szolgál. A FocusNavigationDirection, amelyet átadunk a MoveFocus-nak, meghatározza, hogy milyen irányba mozdítható a fókusz, például First, Last, Up és Down.
Az alábbi példa a MoveFocus-t használja a fókuszált elem módosításához.
// 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 visszaadja azt az objektumot, amely fókuszt kap a fókusz módosítása esetén. Jelenleg a Upcsak a Down, Left, Rightés PredictFocus típusokat támogatja.
Fókuszesemények
A billentyűzetfókuszhoz kapcsolódó események a következők: PreviewGotKeyboardFocus, GotKeyboardFocus és PreviewLostKeyboardFocus, LostKeyboardFocus. Az események csatolt eseményként vannak definiálva az Keyboard osztályban, de könnyebben elérhetők az alapelemosztályok egyenértékű irányított eseményeiként. További információért az eseményekről lásd: Irányított események áttekintése.
GotKeyboardFocus akkor merül fel, amikor az elem megkapja a billentyűzetfókuszt.
LostKeyboardFocus akkor merül fel, ha az elem elveszíti a billentyűzetfókuszt. Ha a PreviewGotKeyboardFocus vagy a PreviewLostKeyboardFocusEvent eseményt kezelik, és a Handled-t true-ra állítják be, akkor a fókusz nem változik.
Az alábbi példa GotKeyboardFocus- és LostKeyboardFocus-eseménykezelőket csatol a TextBox-höz.
<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>
Amikor a TextBox megkapja a billentyűzetfókuszt, a BackgroundTextBox tulajdonsága LightBluelesz.
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
Amikor a TextBox elveszíti a billentyűzetfókuszt, a BackgroundTextBox tulajdonsága visszaáll fehérre.
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
A logikai fókuszhoz kapcsolódó események GotFocus és LostFocus. Ezek az események csatolt eseményként vannak definiálva a FocusManager, de a FocusManager nem teszi elérhetővé a CLR-eseményburkolókat. UIElement és ContentElement kényelmesebben teszik elérhetővé ezeket az eseményeket.
Lásd még
.NET Desktop feedback