Přehled vstupu
subsystému Windows Presentation Foundation (WPF) poskytuje výkonné rozhraní API pro získání vstupu z různých zařízení, včetně myši, klávesnice, dotykového ovládání a pera. Toto téma popisuje služby poskytované WPF a vysvětluje architekturu vstupních systémů.
Vstupní rozhraní API
Primární vstupní expozice rozhraní API se nachází v základních třídách prvků: UIElement, ContentElement, FrameworkElementa FrameworkContentElement. Další informace o základních prvcích naleznete v přehledu základních prvků . Tyto třídy poskytují funkce pro vstupní události související s stisknutí kláves, tlačítky myši, kolečkem myši, pohybem myši, správou fokusu a zachycením myši, abyste mohli uvést několik názvů. Umístěním vstupního rozhraní API na základní elementy, nikoli zacházet se všemi vstupními událostmi jako se službou, vstupní architektura umožňuje zdroj vstupních událostí konkrétním objektem v uživatelském rozhraní a k podpoře schématu směrování událostí, ve kterém má více než jeden prvek příležitost zpracovat vstupní událost. Mnoho vstupních událostí má přidruženou dvojici událostí. Například událost stisknutí klávesy je spojena s událostmi KeyDown a PreviewKeyDown. Rozdíl v těchto událostech spočívá v tom, jak jsou směrovány do cílového prvku. Ukázkové události procházejí stromem prvků od kořenového prvku ke cílovému prvku. Události probublávání putují od cílového prvku k kořenovému prvku. Směrování událostí ve WPF je podrobněji popsáno dále v tomto přehledu a v přehledu směrovaných událostí.
Třídy klávesnice a myši
Kromě vstupního rozhraní API na základních třídách elementů poskytují třídy Keyboard a třídy Mouse další rozhraní API pro práci s klávesnicí a vstupem myši.
Příklady vstupního rozhraní API ve třídě Keyboard jsou vlastnost Modifiers, která vrací ModifierKeys aktuálně stisknutou, a metodu IsKeyDown, která určuje, zda je zadaná klávesa stisknuta.
Následující příklad používá metodu GetKeyStates k určení, zda je Key ve stavu dolů.
// Uses the Keyboard.GetKeyStates to determine if a key is down.
// A bitwise AND operation is used in the comparison.
// e is an instance of KeyEventArgs.
if ((Keyboard.GetKeyStates(Key.Return) & KeyStates.Down) > 0)
{
btnNone.Background = Brushes.Red;
}
' Uses the Keyboard.GetKeyStates to determine if a key is down.
' A bitwise AND operation is used in the comparison.
' e is an instance of KeyEventArgs.
If (Keyboard.GetKeyStates(Key.Return) And KeyStates.Down) > 0 Then
btnNone.Background = Brushes.Red
Příklady vstupního rozhraní API ve třídě Mouse jsou MiddleButton, které získává stav prostředního tlačítka myši, a DirectlyOver, který určuje prvek, nad kterým se právě nachází ukazatel myši.
Následující příklad určuje, zda je LeftButton na myši ve stavu Pressed.
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
UpdateSampleResults("Left Button Pressed");
}
If Mouse.LeftButton = MouseButtonState.Pressed Then
UpdateSampleResults("Left Button Pressed")
End If
V tomto přehledu jsou podrobněji popsány třídy Mouse a Keyboard.
Stylusový vstup
WPF má integrovanou podporu pro Stylus. Stylus je vstup pro pero, který se stal populárním díky Tablet PC. Aplikace WPF mohou považovat pera za myš pomocí rozhraní API myši, ale WPF také zveřejňuje abstrakci pera zařízení, která používá model podobný klávesnici a myši. Všechna rozhraní API související s perem obsahují slovo Stylus.
Vzhledem k tomu, že pero může fungovat jako myš, aplikace, které podporují pouze vstup myši, mohou stále získat určitou úroveň podpory pera automaticky. Pokud se pero používá takovým způsobem, aplikace má možnost zpracovat odpovídající událost pera a pak zpracuje odpovídající událost myši. Kromě toho jsou služby vyšší úrovně, jako je vstup rukopisu, k dispozici také prostřednictvím abstrakce pera zařízení. Další informace o rukopisu jako vstupu naleznete v tématu Začínáme s rukopisem.
Směrování událostí
FrameworkElement může v modelu obsahu obsahovat další prvky jako podřízené prvky, čímž tvoří strom prvků. Ve WPF se může nadřazený prvek účastnit vstupu směrovaného na jeho podřízené prvky nebo jiné potomky zpracováním událostí. To je zvlášť užitečné pro vytváření ovládacích prvků z menších ovládacích prvků, procesu označovaného jako "složení ovládacích prvků" nebo "kompozitování". Další informace o stromech prvků a o tom, jak stromy prvků souvisí s trasami událostí, naleznete v tématu Stromy ve WPF.
Směrování událostí je proces předávání událostí na více prvků, takže konkrétní objekt nebo prvek podél trasy může zvolit, aby nabídl významnou odpověď (prostřednictvím zpracování) události, která mohla být zdrojem jiného prvku. Směrované události používají jeden ze tří mechanismů směrování: přímé, bublající a tunelové propojení. Při přímém směrování je zdrojový prvek jediným prvkem, který je upozorněn a událost není směrována na žádné jiné prvky. Přímá směrovaná událost ale stále nabízí některé další funkce, které jsou k dispozici pouze pro směrované události místo standardních událostí CLR. Bubbling pracuje ve stromu elementů tím, že nejprve upozorní prvek, který událost vyvolal, pak nadřazený element atd. Tunelování začíná v kořenovém prvku stromu elementů a směřuje dolů, končící původním zdrojovým prvkem. Další informace o směrovaných událostech naleznete v tématu Přehled směrovaných událostí.
Vstupní události WPF obvykle přicházejí ve dvojicích, které se skládají z události tunelování a bublinové události. Události tunelování se od bublinových událostí rozlišují použitím předpony "Preview". Například PreviewMouseMove je tunelovací verze události pohybu myší a MouseMove je bublající verze této události. Toto párování událostí je konvence, která je implementována na úrovni prvku a není vlastní schopností systému událostí WPF. Podrobnosti naleznete v části o událostech vstupu WPF v Přehled směrovaných událostí.
Zpracování vstupních událostí
Chcete-li přijímat vstup týkající se prvku, musí být obslužná rutina události přidružena k této konkrétní události. V XAML je to jednoduché: odkazujete na název události jako atribut prvku, který bude naslouchat pro tuto událost. Pak nastavíte hodnotu atributu na jméno obsluhy události, kterou definujete na základě delegáta. Obslužná rutina události musí být napsaná v jazyce, jako je C#, a může být zahrnuta v souboru code-behind.
Události klávesnice se vyskytují, když operační systém hlásí klíčové akce, ke kterým dochází, když je fokus klávesnice na prvku. Události myši a pera spadají do dvou kategorií: události, které hlásí změny umístění ukazatele vzhledem k prvku, a události, které hlásí změny ve stavu tlačítek zařízení.
Příklad události vstupu klávesnice
Následující příklad zaznamenává stisknutí klávesy se šipkou doleva. Vytvoří se StackPanel, který má Button. Obslužná rutina pro události, která naslouchá stisknutí šipky doleva, je přiřazena k instanci Button.
První část příkladu vytvoří StackPanel a Button a připojí obslužnou rutinu události pro KeyDown.
<StackPanel>
<Button Background="AliceBlue"
KeyDown="OnButtonKeyDown"
Content="Button1"/>
</StackPanel>
// Create the UI elements.
StackPanel keyboardStackPanel = new StackPanel();
Button keyboardButton1 = new Button();
// Set properties on Buttons.
keyboardButton1.Background = Brushes.AliceBlue;
keyboardButton1.Content = "Button 1";
// Attach Buttons to StackPanel.
keyboardStackPanel.Children.Add(keyboardButton1);
// Attach event handler.
keyboardButton1.KeyDown += new KeyEventHandler(OnButtonKeyDown);
' Create the UI elements.
Dim keyboardStackPanel As New StackPanel()
Dim keyboardButton1 As New Button()
' Set properties on Buttons.
keyboardButton1.Background = Brushes.AliceBlue
keyboardButton1.Content = "Button 1"
' Attach Buttons to StackPanel.
keyboardStackPanel.Children.Add(keyboardButton1)
' Attach event handler.
AddHandler keyboardButton1.KeyDown, AddressOf OnButtonKeyDown
Druhá část je napsána v kódu a definuje obslužnou rutinu události. Když je stisknutá klávesa se šipkou doleva a Button má fokus klávesnice, obslužná rutina se spustí a změní se Background barva objektu Button. Pokud je stisknutá klávesa, ale není to klávesa šipka vlevo, barva Background prvku Button se změní zpět na výchozí barvu.
private void OnButtonKeyDown(object sender, KeyEventArgs e)
{
Button source = e.Source as Button;
if (source != null)
{
if (e.Key == Key.Left)
{
source.Background = Brushes.LemonChiffon;
}
else
{
source.Background = Brushes.AliceBlue;
}
}
}
Private Sub OnButtonKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
Dim source As Button = TryCast(e.Source, Button)
If source IsNot Nothing Then
If e.Key = Key.Left Then
source.Background = Brushes.LemonChiffon
Else
source.Background = Brushes.AliceBlue
End If
End If
End Sub
Příklad události vstupu myši
V následujícím příkladu se změní barva BackgroundButton, když ukazatel myši vstoupí do Button. Barva Background se obnoví, když myš opustí Button.
První část příkladu vytvoří ovládací prvek StackPanel a ovládací prvek Button, a připojí obslužné rutiny pro události MouseEnter a MouseLeave k Button.
<StackPanel>
<Button Background="AliceBlue"
MouseEnter="OnMouseExampleMouseEnter"
MouseLeave="OnMosueExampleMouseLeave">Button
</Button>
</StackPanel>
// Create the UI elements.
StackPanel mouseMoveStackPanel = new StackPanel();
Button mouseMoveButton = new Button();
// Set properties on Button.
mouseMoveButton.Background = Brushes.AliceBlue;
mouseMoveButton.Content = "Button";
// Attach Buttons to StackPanel.
mouseMoveStackPanel.Children.Add(mouseMoveButton);
// Attach event handler.
mouseMoveButton.MouseEnter += new MouseEventHandler(OnMouseExampleMouseEnter);
mouseMoveButton.MouseLeave += new MouseEventHandler(OnMosueExampleMouseLeave);
' Create the UI elements.
Dim mouseMoveStackPanel As New StackPanel()
Dim mouseMoveButton As New Button()
' Set properties on Button.
mouseMoveButton.Background = Brushes.AliceBlue
mouseMoveButton.Content = "Button"
' Attach Buttons to StackPanel.
mouseMoveStackPanel.Children.Add(mouseMoveButton)
' Attach event handler.
AddHandler mouseMoveButton.MouseEnter, AddressOf OnMouseExampleMouseEnter
AddHandler mouseMoveButton.MouseLeave, AddressOf OnMosueExampleMouseLeave
Druhá část příkladu je napsaná v kódu a definuje obslužné rutiny událostí. Když myš přejde do Button, změní se Background barva Button na SlateGray. Když myš opustí Button, změní se barva Background u Button zpět na AliceBlue.
private void OnMouseExampleMouseEnter(object sender, MouseEventArgs e)
{
// Cast the source of the event to a Button.
Button source = e.Source as Button;
// If source is a Button.
if (source != null)
{
source.Background = Brushes.SlateGray;
}
}
Private Sub OnMouseExampleMouseEnter(ByVal sender As Object, ByVal e As MouseEventArgs)
' Cast the source of the event to a Button.
Dim source As Button = TryCast(e.Source, Button)
' If source is a Button.
If source IsNot Nothing Then
source.Background = Brushes.SlateGray
End If
End Sub
private void OnMosueExampleMouseLeave(object sender, MouseEventArgs e)
{
// Cast the source of the event to a Button.
Button source = e.Source as Button;
// If source is a Button.
if (source != null)
{
source.Background = Brushes.AliceBlue;
}
}
Private Sub OnMosueExampleMouseLeave(ByVal sender As Object, ByVal e As MouseEventArgs)
' Cast the source of the event to a Button.
Dim source As Button = TryCast(e.Source, Button)
' If source is a Button.
If source IsNot Nothing Then
source.Background = Brushes.AliceBlue
End If
End Sub
Textové zadání
Událost TextInput umožňuje naslouchat zadávání textu nezávisle na zařízení. Klávesnice je primárním prostředkem pro zadávání textu, ale řeč, rukopis a další vstupní zařízení můžou také generovat textové zadání.
Pro vstup klávesnice WPF nejprve odešle příslušné KeyDown/KeyUp události. Pokud se tyto události nezpracují a klíč je textový (nikoli řídicí klávesa, jako jsou směrové šipky nebo funkční klávesy), vyvolá se událost TextInput. Mezi událostmi KeyDown/KeyUp a TextInput není vždy jednoduché přiřazení 1:1, protože více stisknutí kláves může generovat jeden znak textového vstupu a jednotlivé stisknutí klávesy může generovat víceznakové řetězce. To platí zejména pro jazyky, jako jsou čínština, japonština a korejština, které používají editory IME (Input Method Editor) k vygenerování tisíců možných znaků v odpovídajících abecedách.
Když WPF odešle událost KeyUp/KeyDown, Key je nastavená na Key.System, pokud se stisknutí kláves může stát součástí události TextInput (pokud je například stisknuta klávesa ALT+S). To umožňuje kódu v obslužné rutině události KeyDown zkontrolovat Key.System a, pokud je nalezena, přenechat zpracování obslužné rutině následně vyvolané události TextInput. V těchto případech lze různé vlastnosti argumentu TextCompositionEventArgs použít k určení původních úhozů na klávesnici. Podobně platí, že pokud je aktivní IME, Key má hodnotu Key.ImeProcesseda ImeProcessedKey dává původní stisk kláves.
Následující příklad definuje obslužnou rutinu pro Click událost a obslužnou rutinu pro KeyDown událost.
První segment kódu nebo značení vytváří uživatelské rozhraní.
<StackPanel KeyDown="OnTextInputKeyDown">
<Button Click="OnTextInputButtonClick"
Content="Open" />
<TextBox> . . . </TextBox>
</StackPanel>
// Create the UI elements.
StackPanel textInputStackPanel = new StackPanel();
Button textInputeButton = new Button();
TextBox textInputTextBox = new TextBox();
textInputeButton.Content = "Open";
// Attach elements to StackPanel.
textInputStackPanel.Children.Add(textInputeButton);
textInputStackPanel.Children.Add(textInputTextBox);
// Attach event handlers.
textInputStackPanel.KeyDown += new KeyEventHandler(OnTextInputKeyDown);
textInputeButton.Click += new RoutedEventHandler(OnTextInputButtonClick);
' Create the UI elements.
Dim textInputStackPanel As New StackPanel()
Dim textInputeButton As New Button()
Dim textInputTextBox As New TextBox()
textInputeButton.Content = "Open"
' Attach elements to StackPanel.
textInputStackPanel.Children.Add(textInputeButton)
textInputStackPanel.Children.Add(textInputTextBox)
' Attach event handlers.
AddHandler textInputStackPanel.KeyDown, AddressOf OnTextInputKeyDown
AddHandler textInputeButton.Click, AddressOf OnTextInputButtonClick
Druhý segment kódu obsahuje obslužné rutiny událostí.
private void OnTextInputKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.O && Keyboard.Modifiers == ModifierKeys.Control)
{
handle();
e.Handled = true;
}
}
private void OnTextInputButtonClick(object sender, RoutedEventArgs e)
{
handle();
e.Handled = true;
}
public void handle()
{
MessageBox.Show("Pretend this opens a file");
}
Private Sub OnTextInputKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.Key = Key.O AndAlso Keyboard.Modifiers = ModifierKeys.Control Then
handle()
e.Handled = True
End If
End Sub
Private Sub OnTextInputButtonClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
handle()
e.Handled = True
End Sub
Public Sub handle()
MessageBox.Show("Pretend this opens a file")
End Sub
Vzhledem k tomu, že vstupní události bublinují trasu události, StackPanel přijímá vstup bez ohledu na to, který prvek má fokus klávesnice. Ovládací prvek TextBox je nejprve upozorněn a obslužná rutina OnTextInputKeyDown
je volána pouze v případě, že TextBox nezpracoval vstup. Pokud se místo události KeyDown použije událost PreviewKeyDown, je jako první volána obslužná rutina OnTextInputKeyDown
.
V tomto příkladu se logika zpracování zapíše dvakrát – jednou pro ctrl+O a znovu pro událost kliknutí na tlačítko. To se dá zjednodušit pomocí příkazů místo přímého zpracování vstupních událostí. Příkazy jsou diskutovány v tomto přehledu a v přehledu Commanding Overview.
Dotykové ovládání a manipulace
Nový hardware a rozhraní API v operačním systému Windows 7 poskytují aplikacím možnost přijímat vstupy z více dotyků současně. WPF umožňuje aplikacím detekovat dotykové ovládání a reagovat na ně podobným způsobem, jako je reakce na jiný vstup, jako je myš nebo klávesnice, vyvoláním událostí, když dojde k dotyku.
WPF zveřejňuje dva typy událostí, když dojde k dotyku: události dotykového ovládání a události manipulace. Dotykové události poskytují nezpracovaná data o každém prstu na dotykovém displeji a jeho pohybu. Události manipulace interpretují vstup jako určité akce. V této části jsou popsány oba typy událostí.
Požadavky
K vývoji aplikace, která reaguje na dotykové ovládání, potřebujete následující komponenty.
Visual Studio 2010
Windows 7.
Zařízení, jako je dotyková obrazovka, která podporuje Windows Touch.
Terminologie
Při diskusi o dotykovém ovládání se používají následující termíny.
Touch je typ uživatelského vstupu, který systém Windows 7 rozpozná. Obvykle je dotykové ovládání inicializováno tak, že prsty umístíte na dotykovou obrazovku. Všimněte si, že zařízení, jako je touchpad, který je běžný na přenosných počítačích, nepodporují dotykové ovládání, pokud zařízení pouze převádí pozici a pohyb prstu jako vstup myši.
multitouch je dotykové ovládání, ke kterému dochází z více než jednoho bodu současně. Windows 7 a WPF podporují vícedotykové ovládání. Kdykoli se v dokumentaci k WPF diskutuje o dotyku, tyto pojmy se vztahují na vícedotykové ovládání.
manipulace nastane, když je dotyk interpretován jako fyzická akce aplikovaná na objekt. Události manipulace ve WPF interpretují vstup jako překládání, rozšiřování nebo otáčení.
touch device
představuje zařízení, které vytváří dotykové vstupy, například jeden prst na dotykové obrazovce.
Ovládací prvky, které reagují na dotykové ovládání
Následující ovládací prvky lze posouvat přetažením prstu přes ovládací prvek, pokud obsahuje obsah, který je posunut mimo zobrazení.
ScrollViewer definuje ScrollViewer.PanningMode připojenou vlastnost, která umožňuje určit, zda je dotykové posouvání povoleno vodorovně, svisle, obojí nebo ani jedno. Vlastnost ScrollViewer.PanningDeceleration určuje, jak rychle se posouvání zpomalí, když uživatel zvedne prst z dotykové obrazovky. Vlastnost ScrollViewer.PanningRatio připojená určuje poměr posunu posouvání k přeložení posunu manipulace.
Dotykové události
Základní třídy, UIElement, UIElement3Da ContentElement, definují události, které můžete přihlásit k odběru, aby vaše aplikace reagovala na dotykové ovládání. Dotykové události jsou užitečné, když vaše aplikace interpretuje dotykové ovládání jako něco jiného než manipulaci s objektem. Například aplikace, která uživateli umožňuje kreslit jedním nebo více prsty, by se přihlásila k odběru dotykových událostí.
Všechny tři třídy definují následující události, které se chovají podobně bez ohledu na definici třídy.
Podobně jako události klávesnice a myši jsou události dotykového ovládání směrované. Události, které začínají Preview
, jsou tunelové události a události, které začínají Touch
, jsou bublinové události. Další informace o trasovaných událostech naleznete v tématu Přehled trasovaných událostí. Při zpracování těchto událostí můžete získat pozici vstupu vzhledem k jakémukoli prvku voláním GetTouchPoint nebo GetIntermediateTouchPoints metody.
Pokud chcete porozumět interakci mezi dotykovými událostmi, zvažte scénář, ve kterém uživatel položí jeden prst na prvek, přesune prst do prvku a pak zvedne prst z prvku. Následující obrázek znázorňuje spuštění událostí bublání (události tunelování jsou kvůli jednoduchosti vynechány).
Dotykové události
Následující seznam popisuje posloupnost událostí na předchozím obrázku.
Událost TouchEnter nastane jednou, když uživatel položí prst na prvek.
Událost TouchDown nastane jednou.
Událost TouchMove se vyskytuje vícekrát, když uživatel přesune prst uvnitř prvku.
Událost TouchUp nastane jednou, když uživatel zvedne prst z prvku.
Událost TouchLeave nastane jednou.
Pokud se použije více než dva prsty, dojde u každého prstu k událostem.
Události manipulace
V případech, kdy aplikace umožňuje uživateli manipulovat s objektem, třída UIElement definuje události manipulace. Na rozdíl od dotykových událostí, které jednoduše hlásí pozici dotykového ovládání, hlásí události manipulace, jak lze vstup interpretovat. Existují tři typy manipulace, překlad, rozšíření a rotace. Následující seznam popisuje, jak vyvolat tři typy manipulace.
Položte prst na objekt a přesuňte prst přes dotykovou obrazovku, aby se vyvolala manipulace s překladem. Tím se objekt obvykle přesune.
Položte dva prsty na objekt a přesuňte je blíž k sobě nebo od sebe, abyste vyvolali zvětšení či zmenšení. Obvykle se tím změní velikost objektu.
Položte dva prsty na objekt a otočte prsty kolem sebe, abyste vyvolali manipulaci s otočením. Obvykle se tím objekt otočí.
Současně může dojít k více typům manipulace.
Když přimějete objekty reagovat na manipulaci, můžete udělat, aby objekt vypadal, jako by měl setrvačnost. Díky tomu můžou objekty simulovat fyzický svět. Například pokud posunete knihu po stole, bude kniha pokračovat v pohybu i po uvolnění. WPF umožňuje simulovat toto chování vyvoláním událostí manipulace poté, co prsty uživatele uvolní objekt.
Informace o tom, jak vytvořit aplikaci, která uživateli umožňuje přesunout, změnit velikost a otočit objekt, naleznete v tématu Návod: Vytvoření vaší první dotykové aplikace.
UIElement definuje následující události manipulace.
Ve výchozím nastavení UIElement tyto události manipulace neobdrží. Pokud chcete na UIElementpřijímat události manipulace, nastavte UIElement.IsManipulationEnabled na true
.
Cesta provádění událostí manipulace
Představte si scénář, kdy uživatel vyvolá objekt. Uživatel umístí prst na objekt, přesune prst přes dotykovou obrazovku na krátkou vzdálenost a pak prst zvedne během pohybu. Výsledkem je, že se objekt přesune pod prstem uživatele a bude pokračovat v pohybu poté, co uživatel zvedne prst.
Následující obrázek znázorňuje cestu provádění událostí manipulace a důležité informace o jednotlivých událostech.
Události manipulace
Následující seznam popisuje posloupnost událostí na předchozím obrázku.
Událost ManipulationStarting nastane, když uživatel umístí prst na objekt. Mimo jiné vám tato událost umožňuje nastavit vlastnost ManipulationContainer. V následujících událostech bude pozice manipulace relativní vůči ManipulationContainer. V událostech jiných než ManipulationStartingje tato vlastnost jen pro čtení, takže ManipulationStarting událost je jediný čas, kdy můžete tuto vlastnost nastavit.
Událost ManipulationStarted nastává příště. Tato událost hlásí původ manipulace.
K události ManipulationDelta dochází několikrát, když se prsty uživatele pohybují na dotykové obrazovce. Vlastnost DeltaManipulation třídy ManipulationDeltaEventArgs hlásí, zda je manipulace interpretována jako pohyb, rozšíření nebo překlad. To je místo, kde provádíte většinu práce manipulace s objektem.
Událost ManipulationInertiaStarting nastane, když prsty uživatele ztratí kontakt s objektem. Tato událost umožňuje určit zpomalení manipulací během nečinnosti. To znamená, že objekt může emulovat různé fyzické mezery nebo atributy, pokud zvolíte. Předpokládejme například, že vaše aplikace má dva objekty, které představují položky ve fyzickém světě, a jedna je těžší než druhá. Můžete zařídit, aby těžší objekt zpomaloval rychleji než lehčí objekt.
K události ManipulationDelta dochází vícekrát, jakmile nastane setrvačnost. Tato událost nastane, když se prsty uživatele pohybují přes dotykovou obrazovku a při simulaci nečinnosti WPF. Jinými slovy, ManipulationDelta nastane před a po události ManipulationInertiaStarting. Vlastnost ManipulationDeltaEventArgs.IsInertial hlásí, zda dojde k události ManipulationDelta během nečinnosti, takže můžete zkontrolovat tuto vlastnost a provádět různé akce v závislosti na jeho hodnotě.
Událost ManipulationCompleted nastane, když manipulace a jakákoli inertia skončí. To znamená, že jakmile dojde ke všem událostem ManipulationDelta, dojde k ManipulationCompleted události, aby signalizovala, že manipulace je dokončená.
UIElement také definuje událost ManipulationBoundaryFeedback. K této události dochází, když je metoda ReportBoundaryFeedback volána při události ManipulationDelta. Událost ManipulationBoundaryFeedback umožňuje aplikacím nebo komponentám poskytovat vizuální zpětnou vazbu, když objekt dosáhne hranice. Třída Window například zpracovává událost ManipulationBoundaryFeedback, aby se okno mírně přesunulo, když dojde k jeho okraji.
Manipulaci můžete zrušit voláním metody Cancel u argumentů události v jakékoli události manipulace s výjimkou ManipulationBoundaryFeedback události. Když voláte Cancel, už nejsou vyvolávány události manipulace a události myši se stávají událostmi dotykového ovládání. Následující tabulka popisuje vztah mezi časem zrušení manipulace a událostmi myši, ke kterým dochází.
Událost, kdy je volána funkce Cancel | Události myši u vstupu, ke kterým již došlo |
---|---|
ManipulationStarting a ManipulationStarted | Stisknutí tlačítka myši. |
ManipulationDelta | Události stisknutí tlačítka myši a pohybu myši. |
ManipulationInertiaStarting a ManipulationCompleted | Události stisku tlačítka myši, pohyb myší a uvolnění tlačítka myši. |
Všimněte si, že pokud voláte Cancel, když je manipulace v nečinnosti, metoda vrátí false
a vstup nevyvolává události myši.
Vztah mezi událostmi dotykového ovládání a manipulace
UIElement může vždy přijímat dotykové události. Pokud je vlastnost IsManipulationEnabled nastavena na true
, může UIElement přijímat události dotykového ovládání i manipulace. Pokud TouchDown událost není zpracována (tj. vlastnost Handled je false
), logika manipulace zachycuje dotyk prvku a generuje události manipulace. Pokud je vlastnost Handled nastavena na true
v události TouchDown, logika manipulace negeneruje události manipulace. Následující obrázek znázorňuje vztah mezi dotykovými událostmi a událostmi manipulace.
dotykové a manipulační události
Následující seznam popisuje vztah mezi událostmi dotykového ovládání a manipulace, které jsou znázorněny na předchozím obrázku.
Když první dotykové zařízení vygeneruje událost TouchDown na UIElement, logika manipulace volá metodu CaptureTouch, která generuje GotTouchCapture událost.
Když dojde k GotTouchCapture, logika manipulace volá metodu Manipulation.AddManipulator, která generuje ManipulationStarting událost.
Když dojde k TouchMove událostí, logika manipulace vygeneruje události ManipulationDelta, ke kterým dochází před událostí ManipulationInertiaStarting.
Když poslední dotykové zařízení na elementu vyvolá TouchUp událost, logika manipulace vygeneruje událost ManipulationInertiaStarting.
Ohnisko
Existují dva hlavní koncepty, které se týkají fokusu ve WPF: fokus klávesnice a logický fokus.
Fokus klávesnice
Fokus klávesnice odkazuje na prvek, který přijímá vstup klávesnice. Na celé ploše může být jenom jeden prvek, který má fokus klávesnice. Ve WPF bude prvek s fokusem klávesnice mít IsKeyboardFocused nastaven na true
. Metoda KeyboardFocusedElement statická vrátí prvek, který má aktuálně klávesový fokus.
Fokus klávesnice lze získat přechodem na prvek pomocí klávesy Tab nebo kliknutím myší na určité prvky, například na TextBox. Fokus klávesnice lze také získat programově pomocí metody Focus ve třídě Keyboard. Focus se pokouší zaměřit zadaný prvek klávesnicovým fokusem. Prvek vrácený Focus je prvek, který má aktuálně fokus klávesnice.
Aby prvek získal fokus klávesnice, musí být vlastnost Focusable a vlastnosti IsVisible nastaveny na true. Některé třídy, například Panel, mají ve výchozím nastavení Focusable nastaveny na false
; proto může být nutné nastavit tuto vlastnost na true
pokud chcete, aby tento prvek mohl získat fokus.
Následující příklad používá Focus k nastavení fokusu klávesnice na Button. Doporučené místo pro nastavení počátečního zaměření v aplikaci je v obslužné rutině události Loaded.
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
Další informace o fokusu klávesnice najdete v tématu Přehled fokusu.
Logický fokus
Logický fokus odkazuje na FocusManager.FocusedElement v rozsahu fokusu. V aplikaci může existovat více prvků, které mají logický fokus, ale může existovat pouze jeden prvek, který má logický fokus v konkrétním oboru fokusu.
Fokusový rozsah je kontejnerový prvek, který sleduje FocusedElement ve svém rozsahu. Když zaměření opustí oblast fokusu, fokusovaný prvek ztratí klávesové zaměření, ale zachová logické zaměření. Když se fokus vrátí do oblasti zaměření, zaostřený prvek získá fokus klávesnice. To umožňuje změnit klávesnicový fokus mezi více oblastech fokusu, ale zajistí, že zaostřený prvek v rámci oblasti fokusu zůstane zaostřeným prvkem při návratu fokusu.
Prvek lze převést na rozsah fokusu v jazyku XAML (Extensible Application Markup Language) nastavením FocusManager připojené vlastnosti IsFocusScope na true
nebo v kódu nastavením připojené vlastnosti pomocí SetIsFocusScope metody.
Následující příklad nastaví připojenou vlastnost IsFocusScope, čímž vytvoří z StackPanel oblast zaměření.
<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)
Třídy ve WPF, které jsou ve výchozím nastavení rozsahy fokusu, jsou Window, Menu, ToolBara ContextMenu.
Prvek s klávesnicovým zaměřením bude mít také logické zaměření pro oblast zaměření, do které patří; proto nastavení zaměření na prvek pomocí metody Focus na třídě Keyboard nebo na třídách základních elementů se pokusí dát prvku klávesnicové i logické zaměření.
Pokud chcete určit prioritní prvek v oboru fokusu, použijte GetFocusedElement. Pokud chcete změnit prioritní prvek pro rozsah fokusu, použijte SetFocusedElement.
Další informace o logickém fokusu najdete v části Přehled fokusu.
Umístění myši
Vstupní rozhraní API WPF poskytuje užitečné informace týkající se souřadnicových prostorů. Například souřadnice (0,0)
je levá horní souřadnice, ale v levém horním rohu kterého prvku ve stromu? Prvek, který je vstupním cílem? Prvek, ke kterému jste připojili událostní obsluhu? Nebo něco jiného? Aby nedocházelo k nejasnostem, vstupní rozhraní API WPF vyžaduje, abyste při práci se souřadnicemi získanými prostřednictvím myši zadali svůj referenční rámec. Metoda GetPosition vrátí souřadnici ukazatele myši vzhledem k zadanému prvku.
Zachycení myši
Zařízení myši konkrétně uchovávají modální charakteristiku známou jako zachycení myši. Zachytávání myší se používá k zachování přechodného vstupního stavu při spuštění operace přetažení, takže k jiným operacím zahrnujícím nominální pozici ukazatele myši na obrazovce nemusí nutně docházet. Během přetahování uživatel nemůže kliknout, aniž by přerušil přetažení, což činí většinu vizuálních prvků při najetí myší nevhodnou, zatímco zachycení myši je drženo u počátku přetažení. Vstupní systém zveřejňuje rozhraní API, která můžou určit stav zachycení myši, a také rozhraní API, která mohou vynutit zachycení myši na určitý prvek nebo vymazat stav zachycení myši. Další informace o operacích přetažení naleznete v tématu Přehled přetažení.
Příkazy
Příkazy umožňují zpracování vstupu na sémantické úrovni než vstup zařízení. Příkazy jsou jednoduché direktivy, například Cut
, Copy
, Paste
nebo Open
. Příkazy jsou užitečné pro centralizaci logiky příkazů. Stejný příkaz může být přístupný z Menu, na ToolBarnebo přes klávesovou zkratku. Příkazy také poskytují mechanismus pro zakázání ovládacích prvků, když se příkaz stane nedostupným.
RoutedCommand je implementací WPF ICommand. Při spuštění RoutedCommand se na cíli příkazu vyvolají události PreviewExecuted a Executed, které procházejí stromem prvků tunelováním a nabubláváním, podobně jako jiné vstupy. Pokud cíl příkazu není nastavený, bude cílem příkazu prvek s fokusem klávesnice. Logika, která provede příkaz, je připojena k CommandBinding. Když Executed událost dosáhne CommandBinding pro daný příkaz, zavolá se ExecutedRoutedEventHandler na CommandBinding. Tato obslužná rutina provede akci příkazu.
Další informace o příkazech najdete v tématu Přehled příkazů.
WPF poskytuje knihovnu běžných příkazů, které se skládají z ApplicationCommands, MediaCommands, ComponentCommands, NavigationCommandsa EditingCommandsnebo můžete definovat vlastní.
Následující příklad ukazuje, jak nastavit MenuItem tak, aby po kliknutí vyvolá Paste příkaz na TextBoxza předpokladu, že TextBox má fokus klávesnice.
<StackPanel>
<Menu>
<MenuItem Command="ApplicationCommands.Paste" />
</Menu>
<TextBox />
</StackPanel>
// Creating the UI objects
StackPanel mainStackPanel = new StackPanel();
TextBox pasteTextBox = new TextBox();
Menu stackPanelMenu = new Menu();
MenuItem pasteMenuItem = new MenuItem();
// Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem);
mainStackPanel.Children.Add(stackPanelMenu);
mainStackPanel.Children.Add(pasteTextBox);
// Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste;
// Setting the command target to the TextBox
pasteMenuItem.CommandTarget = pasteTextBox;
' Creating the UI objects
Dim mainStackPanel As New StackPanel()
Dim pasteTextBox As New TextBox()
Dim stackPanelMenu As New Menu()
Dim pasteMenuItem As New MenuItem()
' Adding objects to the panel and the menu
stackPanelMenu.Items.Add(pasteMenuItem)
mainStackPanel.Children.Add(stackPanelMenu)
mainStackPanel.Children.Add(pasteTextBox)
' Setting the command to the Paste command
pasteMenuItem.Command = ApplicationCommands.Paste
Další informace o příkazech ve WPF naleznete v tématu Commanding Overview.
Vstupní systém a základní prvky
Vstupní události, jako jsou připojené události definované třídami Mouse, Keyboarda Stylus, jsou vyvolány vstupním systémem a vloženy do konkrétní pozice v objektovém modelu na základě testování zásahu do vizuálního stromu za běhu času.
Všechny události, které Mouse, Keyboarda Stylus definují jako připojenou událost, jsou také opět vystaveny základními třídami elementů UIElement a ContentElement jako nová směrovaná událost. Směrované události základního prvku jsou generovány třídami, které zpracovávají původní připojenou událost a opětovně používají data události.
Když se vstupní událost přidružuje ke konkrétnímu zdrojovému prvku prostřednictvím implementace vstupní události základního elementu, může být směrována přes zbytek trasy události, která je založena na kombinaci logických a vizuálních stromových objektů, a být zpracována kódem aplikace. Obecně je pohodlnější zpracovávat tyto vstupní události související se zařízeními pomocí směrovaných událostí na UIElement a ContentElement, protože můžete použít intuitivnější syntaxi obslužné rutiny událostí jak v XAML, tak v kódu. Můžete se rozhodnout zpracovat připojenou událost, která místo toho spustila proces, ale došlo by k několika problémům: Připojená událost může být označena zpracováním třídy základního elementu a k připojení obslužných rutin pro připojené události je potřeba použít metody přístupového objektu místo skutečné syntaxe událostí.
Co dál
Nyní máte několik technik pro zpracování vstupu ve WPF. Měli byste také mít lepší přehled o různých typech vstupních událostí a mechanismech směrovaných událostí používaných WPF.
K dispozici jsou další prostředky, které podrobněji vysvětlují prvky architektury WPF a směrování událostí. Další informace najdete v následujících přehledech: Přehled Commanding , Přehled Focusu , Přehled základních prvků , Stromy ve WPF a Přehled směrovaných událostí .
Viz také
- Přehled zaměření
- Přehled příkazů
- Přehled směrovaných událostí
- Přehled základních elementů
- vlastnosti
.NET Desktop feedback