Input Overview
O Windows Presentation Foundation (WPF) o subsistema fornece um poderoso API para obter a entrada de uma variedade de dispositivos, incluindo o mouse, teclado, toque e caneta. Este tópico descreve os serviços fornecidos pelo WPF e explica a arquitetura dos sistemas de entrada.
Este tópico contém as seguintes seções.
- Input API
- Event Routing
- Handling Input Events
- Text Input
- Toque e manipulação
- Focus
- Mouse Position
- Mouse Capture
- Commands
- The Input System and Base Elements
- What's Next
- Tópicos relacionados
Input API
A entrada principal API exposição encontra-se nas classes de elemento base: UIElement, ContentElement, FrameworkElement, and FrameworkContentElement. Para obter mais informações sobre os elementos base, consulte Visão geral sobre elementos base. Essas classes fornecem a funcionalidade para eventos de entrada relacionados a pressionamentos de teclas, botões do mouse, roda do mouse, movimento do mouse, gerenciamento do foco e captura do mouse, para citar alguns. Colocando a entrada API em elementos de base, em vez de tratar todos os eventos de entrada como um serviço, a arquitetura de entrada permite que os eventos de entrada para ser originado por um objeto específico na interface de usuário e para oferecer suporte a um esquema de roteamento de eventos, onde mais de um elemento tem uma oportunidade para manipular um evento de entrada. Muitos eventos de entrada tem um par de eventos associados a eles. Por exemplo, a chave para baixo de eventos está associada a KeyDown e PreviewKeyDown eventos. The difference in these events is in how they are routed to the target element. Túnel de eventos de visualização para baixo na árvore de elemento do elemento raiz para o elemento de destino. Eventos de bubbling bolhas do elemento de destino para o elemento raiz. Event routing in WPF is discussed in more detail later in this overview and in the Visão geral sobre eventos roteados.
Keyboard and Mouse Classes
Além de para a entrada API nas classes de elemento base, o Keyboard classe e Mouse classes fornecem adicionais API para trabalhar com entrada de teclado e mouse.
Exemplos de entrada API na Keyboard classe são o Modifiers propriedade, que retorna o ModifierKeys pressionadas no momento e o IsKeyDown método, que determina se uma chave especificada é pressionada.
The following example uses the GetKeyStates method to determine if a Key is in the down state.
' 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
// 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;
}
Exemplos de entrada API sobre o Mouse classe são MiddleButton, que obtém o estado do botão do meio do mouse, e DirectlyOver, que obtém o elemento que o ponteiro do mouse está sobre atualmente.
The following example determines whether the LeftButton on the mouse is in the Pressed state.
If Mouse.LeftButton = MouseButtonState.Pressed Then
UpdateSampleResults("Left Button Pressed")
End If
if (Mouse.LeftButton == MouseButtonState.Pressed)
{
UpdateSampleResults("Left Button Pressed");
}
The Mouse and Keyboard classes are covered in more detail throughout this overview.
Stylus Input
WPF has integrated support for the Stylus. O Stylus é uma entrada de caneta popularizada pela Tablet PC. WPFaplicativos podem tratar a caneta como um mouse usando o mouse API, mas WPF também expõe uma abstração de dispositivo stylus que usam um modelo semelhante ao teclado e mouse. All stylus-related APIs contain the word "Stylus".
Because the stylus can act as a mouse, applications that support only mouse input can still obtain some level of stylus support automatically. When the stylus is used in such a manner, the application is given the opportunity to handle the appropriate stylus event and then handles the corresponding mouse event. In addition, higher-level services such as ink input are also available through the stylus device abstraction. For more information about ink as input, see Getting Started with Ink.
Event Routing
A FrameworkElement can contain other elements as child elements in its content model, forming a tree of elements. In WPF, the parent element can participate in input directed to its child elements or other descendants by handing events. This is especially useful for building controls out of smaller controls, a process known as "control composition" or "compositing." Para obter mais informações sobre árvores de elementos e como árvores de elementos se relacionam com rotas de eventos, consulte Árvores em WPF.
Event routing is the process of forwarding events to multiple elements, so that a particular object or element along the route can choose to offer a significant response (through handling) to an event that might have been sourced by a different element. Uso de eventos, um dos três mecanismos de roteamento de roteados: Direct, bubbling e encapsulamento. In direct routing, the source element is the only element notified, and the event is not routed to any other elements. However, the direct routed event still offers some additional capabilities that are only present for routed events as opposed to standard CLR events. Bubbling works up the element tree by first notifying the element that sourced the event, then the parent element, and so on. Encapsulamento começa na raiz da árvore de elementos e funciona para baixo, terminando com o elemento de origem original. For more information about routed events, see Visão geral sobre eventos roteados.
WPF input events generally come in pairs that consists of a tunneling event and a bubbling event. Tunneling events are distinguished from bubbling events with the "Preview" prefix. For instance, PreviewMouseMove is the tunneling version of a mouse move event and MouseMove is the bubbling version of this event. This event pairing is a convention that is implemented at the element level and is not an inherent capability of the WPF event system. For details, see the WPF Input Events section in Visão geral sobre eventos roteados.
Handling Input Events
To receive input on an element, an event handler must be associated with that particular event. Em XAML isso é simples: Você pode consultar o nome do evento como um atributo do elemento que escutará para este evento. Then, you set the value of the attribute to the name of the event handler that you define, based on a delegate. The event handler must be written in code such as C# and can be included in a code-behind file.
Keyboard events occur when the operating system reports key actions that occur while keyboard focus is on an element. Mouse e stylus eventos cada classificados em duas categorias: eventos que altera o relatório na posição do ponteiro em relação ao elemento e eventos que altera o relatório em que o estado dos botões do dispositivo.
Keyboard Input Event Example
O exemplo a seguir ouve um pressionamento de tecla de seta para a esquerda. A StackPanel is created that has a Button. An event handler to listen for the left arrow key press is attached to the Button instance.
The first section of the example creates the StackPanel and the Button and attaches the event handler for the KeyDown.
<StackPanel>
<Button Background="AliceBlue"
KeyDown="OnButtonKeyDown"
Content="Button1"/>
</StackPanel>
' 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
// 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);
The second section is written in code and defines the event handler. When the left arrow key is pressed and the Button has keyboard focus, the handler runs and the Background color of the Button is changed. If the key is pressed, but it is not the left arrow key, the Background color of the Button is changed back to its starting color.
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
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;
}
}
}
Mouse Input Event Example
In the following example, the Background color of a Button is changed when the mouse pointer enters the Button. The Background color is restored when the mouse leaves the Button.
The first section of the example creates the StackPanel and the Button control and attaches the event handlers for the MouseEnter and MouseLeave events to the Button.
<StackPanel>
<Button Background="AliceBlue"
MouseEnter="OnMouseExampleMouseEnter"
MouseLeave="OnMosueExampleMouseLeave">Button
</Button>
</StackPanel>
' 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
// 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);
A segunda seção do exemplo é escrita em código e define os manipuladores de eventos. When the mouse enters the Button, the Background color of the Button is changed to SlateGray. When the mouse leaves the Button, the Background color of the Button is changed back to AliceBlue.
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 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 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
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;
}
}
Text Input
The TextInput event enables you to listen for text input in a device-independent manner. The keyboard is the primary means of text input, but speech, handwriting, and other input devices can generate text input also.
Para a entrada do teclado, WPF primeiro envia apropriadas KeyDown/KeyUp eventos. If those events are not handled and the key is textual (rather than a control key such as directional arrows or function keys), then a TextInput event is raised. There is not always a simple one-to-one mapping between KeyDown/KeyUp and TextInput events because multiple keystrokes can generate a single character of text input and single keystrokes can generate multi-character strings. Isso é especialmente verdadeiro para idiomas como chinês, japonês e coreano que usam Input Method Editors (IMEs) para gerar milhares de caracteres possíveis em seus alfabetos correspondentes.
Quando WPF envia um KeyUp/KeyDown evento, Key for definido como Key.System se os pressionamentos de tecla poderiam se tornar parte de um TextInput evento (se ALT + S é pressionado, por exemplo). Isso permite que o código em um KeyDown o manipulador de eventos para verificar se há Key.System e, se encontrado, deixe o processamento para o manipulador do subseqüentemente elevado TextInput de evento. In these cases, the various properties of the TextCompositionEventArgs argument can be used to determine the original keystrokes. Similarly, if an IME is active, Key has the value of Key.ImeProcessed, and ImeProcessedKey gives the original keystroke or keystrokes.
O exemplo a seguir define um manipulador para o Click evento e um manipulador para o KeyDown de evento.
The first segment of code or markup creates the user interface.
<StackPanel KeyDown="OnTextInputKeyDown">
<Button Click="OnTextInputButtonClick"
Content="Open" />
<TextBox> . . . </TextBox>
</StackPanel>
' 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
// 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);
O segundo segmento de código contém os manipuladores de eventos.
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
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");
}
Because input events bubble up the event route, the StackPanel receives the input regardless of which element has keyboard focus. The TextBox control is notified first and the OnTextInputKeyDown handler is called only if the TextBox did not handle the input. If the PreviewKeyDown event is used instead of the KeyDown event, the OnTextInputKeyDown handler is called first.
In this example, the handling logic is written two times—one time for CTRL+O, and again for button's click event. This can be simplified by using commands, instead of handling the input events directly. Commands are discussed in this overview and in Visão geral de Comando.
Toque e manipulação
API no sistema operacional Windows 7 e o novo hardware fornecem aplicativos a capacidade de receber entrada de vários "toques" simultaneamente. WPFpermite que aplicativos detectar e responder ao toque de maneira semelhante ao responder a outra entrada, como, por exemplo, o mouse ou teclado, levantando eventos quando ocorre de toque.
WPFexpõe dois tipos de eventos quando ocorre de toque: Toque em eventos e eventos de manipulação. Toque de eventos fornecem dados brutos sobre cada dedo na tela de toque e seu movimento. Eventos de manipulação interpretam a entrada como determinadas ações. Ambos os tipos de eventos são discutidos nesta seção.
Prerequisites
Você precisa os seguintes componentes para desenvolver um aplicativo que responda ao toque.
Microsoft Visual Studio 2010.
O Windows 7.
Um dispositivo, como, por exemplo, uma tela de toque, que oferece suporte a toque do Windows.
Terminology
Os seguintes termos são usados quando o toque é discutido.
Toque é um tipo de entrada do usuário é reconhecida pelo Windows 7. Normalmente, o toque é iniciado colocando os dedos em uma tela sensível. Observe que toque não suporte a dispositivos como, por exemplo, um touchpad que é comum em computadores laptop se o dispositivo simplesmente converte o dedo posição e o movimento como entrada de mouse.
Multitouch é o toque que ocorre a partir de mais de um ponto simultaneamente. Windows 7 e WPF oferece suporte a multitouch. Sempre que o toque é discutido na documentação do WPF, os conceitos se aplicam a multitouch.
A manipulação ocorre quando o toque é interpretado como uma ação física que é aplicada a um objeto. Em WPF, os eventos de manipulação interpretam a entrada como uma tradução, expansão ou manipulação de rotação.
A touch device representa um dispositivo que produz a entrada por toque, como um único dedo em uma tela sensível ao toque.
Controles que responder ao toque
Os seguintes controles podem ser rolados arrastando um dedo entre o controle se ele tiver conteúdo que é rolado fora de visão.
O ScrollViewer define o ScrollViewer.PanningMode anexado propriedade permite que você especifique se a panorâmica de toque está habilitado na horizontal, vertical, ambos ou nenhum. O ScrollViewer.PanningDeceleration propriedade especifica a rapidez com a rolagem lento quando o usuário levanta o dedo na tela sensível ao toque. O ScrollViewer.PanningRatio propriedade anexada Especifica a proporção de deslocamento de rolagem para traduzir o deslocamento de manipulação.
Eventos de toque.
As classes base, UIElement, UIElement3D, e ContentElement, definir eventos que você pode se inscrever para seu aplicativo irá responder ao toque. Toque de eventos são úteis quando seu aplicativo interpreta o toque como algo diferente de manipulação de um objeto. Por exemplo, um aplicativo que permite que um usuário desenhar com um ou mais dedos assinar eventos de toque.
Todas as três classes definem os eventos a seguir, que se comportam da mesma forma, independentemente da classe de definição.
Como eventos de teclado e mouse, o toque são eventos roteados. Os eventos que começam com Preview são encapsulamento eventos e os eventos que começam com Touch são bubbling eventos. For more information about routed events, see Visão geral sobre eventos roteados. Quando você manipular esses eventos, você pode obter a posição da entrada, em relação a qualquer elemento, chamando o GetTouchPoint ou GetIntermediateTouchPoints método.
Compreender a interação entre os eventos de toque, considere o cenário onde um usuário coloca um dedo em um elemento, move o dedo no elemento e, em seguida, levanta o dedo do elemento. A ilustração a seguir mostra a execução dos eventos bubbling (os eventos de encapsulamento são omitidos por simplicidade).
Eventos de toque.
A lista a seguir descreve a seqüência dos eventos na ilustração anterior.
O TouchEnter evento ocorre uma vez quando o usuário coloca um dedo no elemento.
O TouchDown evento ocorre uma vez.
O TouchMove evento ocorre várias vezes à medida que o usuário move o dedo dentro do elemento.
O TouchUp evento ocorre uma vez quando o usuário levanta o dedo do elemento.
O TouchLeave evento ocorre uma vez.
Quando mais de dois dedos são usados, os eventos ocorrem para cada dedo.
Eventos de manipulação
Para casos em que um aplicativo permite que o usuário manipular um objeto, o UIElement define a classe de manipulação de eventos. Ao contrário dos eventos de toque apenas relatam a posição de toque, os eventos de manipulação de relatório como a entrada pode ser interpretada. Existem três tipos de manipulações, tradução, expansão e rotação. A lista a seguir descreve como os três tipos de manipulações de invocação.
Coloque um dedo em um objeto e mover o dedo em toda a tela sensível ao toque para invocar uma manipulação de tradução. Geralmente, isso move o objeto.
Colocar dois dedos em um objeto e mova os dedos, perto juntos ou futuramente, além de uns aos outros para invocar uma manipulação de expansão. Geralmente, isso redimensiona o objeto.
Colocar dois dedos em um objeto e girar os dedos ao redor de si para invocar uma manipulação de rotação. Geralmente, isso gira o objeto.
Mais de um tipo de manipulação de pode ocorrer simultaneamente.
Quando você fazer com que os objetos responder às manipulações, você pode fazer com que o objeto parece ter inércia. Isso pode fazer com que os objetos simular o mundo físico. Por exemplo, quando você pressionar um livro em uma tabela, se você pressionar o disco rígido suficiente para o catálogo continuará mover depois liberá-lo. WPFpermite simular esse comportamento levantando eventos de manipulação após os dedos do usuário libera o objeto.
Para obter informações sobre como criar um aplicativo que permite que o usuário mover, redimensionar e girar um objeto, consulte Demonstra Passo a passo: Criando seu primeiro aplicativo de toque.
O UIElement define os seguintes eventos de manipulação.
Por padrão, um UIElement não recebe esses eventos de manipulação. Para receber eventos de manipulação em um UIElement, defina UIElement.IsManipulationEnabled para true.
O caminho de execução de manipulação de eventos
Considere um cenário onde o usuário "lança" um objeto. O usuário coloca um dedo no objeto, percorre o dedo na tela de toque para uma pequena distância e, em seguida, levanta o dedo, enquanto ele está se movendo. O resultado disso é que o objeto moverá sob os dedos do usuário e continuar a mover depois que o usuário levanta o dedo.
A ilustração a seguir mostra o caminho de execução de eventos de manipulação e informações importantes sobre cada evento.
Eventos de manipulação
A lista a seguir descreve a seqüência dos eventos na ilustração anterior.
O ManipulationStarting evento ocorre quando o usuário coloca um dedo no objeto. Entre outras coisas, esse evento permite que você defina a ManipulationContainer propriedade. Os eventos subseqüentes, a posição da manipulação de será relativa ao ManipulationContainer. Nos eventos diferente de ManipulationStarting, esta propriedade é somente leitura, então o ManipulationStarting o evento é o único momento em que você pode definir essa propriedade.
O ManipulationStarted evento ocorre Avançar. Esse evento informa que a origem da manipulação de.
O ManipulationDelta evento ocorre várias vezes como mover os dedos de um usuário em uma tela sensível ao toque. O DeltaManipulation propriedade da ManipulationDeltaEventArgs classe reporta se a manipulação é interpretada como movimento, expansão ou tradução. Isso é onde você executar a maior parte do trabalho de manipulação de um objeto.
O ManipulationInertiaStarting evento ocorre quando os dedos do usuário perdessem o contato com o objeto. Esse evento permite que você especifique a desaceleração a manipulações durante inércia. Isso é para que seu objeto pode emular os espaços físicos diferentes ou atributos se você escolher. Por exemplo, suponha que seu aplicativo tiver dois objetos que representam os itens no mundo físico e um é maior do que o outro. Você pode fazer com que o objeto mais pesado desaceleram mais rápido do que o objeto mais claro.
O ManipulationDelta evento ocorre várias vezes, como ocorre a inércia. Observe que esse evento ocorre quando os dedos do usuário se mover entre a tela sensível ao toque e WPF simula inércia. Em outras palavras, ManipulationDelta antes e depois o evento deManipulationInertiaStarting . O ManipulationDeltaEventArgs.IsInertial relatórios de propriedade se a ManipulationDelta evento ocorre durante a inércia, para que possa verificar essa propriedade e executar ações diferentes, dependendo do valor.
O ManipulationCompleted evento ocorre quando a manipulação e qualquer extremidades inércia. Isto é, após todos os ManipulationDelta eventos ocorrem, o ManipulationCompleted ocorre um evento para sinalizar que a manipulação está concluída.
O UIElement também define o ManipulationBoundaryFeedback de evento. Esse evento ocorre quando o ReportBoundaryFeedback método é chamado na ManipulationDelta de evento. O ManipulationBoundaryFeedback evento permite que aplicativos ou componentes para fornecer um feedback visual quando um objeto atinge um limite. Por exemplo, o Window identificadores de classe de ManipulationBoundaryFeedback o evento para fazer com que a janela para mover um pouco de quando sua borda é encontrada.
Você pode cancelar a manipulação chamando o Cancel método sobre os argumentos de evento em qualquer evento de manipulação, exceto ManipulationBoundaryFeedback de evento. Quando você chamar Cancel, os eventos de manipulação não são gerados e os eventos de mouse ocorrem nos sensível ao toque. A tabela a seguir descreve a relação entre o momento em que a manipulação é cancelada e os eventos de mouse que ocorrem.
O evento que cancelar é chamado em |
Os eventos de mouse que ocorrem para entrada já ocorreu |
---|---|
Eventos de mouse. |
|
Mouse para baixo e eventos de movimento do mouse. |
|
Mouse para baixo, movimento do mouse e eventos de mouse. |
Observe que, se você chamar Cancel quando a manipulação está na inércia, o método retorna false e a entrada não dispara eventos de mouse.
A relação entre o toque e a eventos de manipulação
A UIElement pode sempre receber eventos de contato. Quando o IsManipulationEnabled for definida como true, um UIElement pode receber eventos de toque e a manipulação. Se a TouchDown evento não é tratado (isto é, o Handled é a propriedade false), a lógica de manipulação captura o toque para o elemento e gera os eventos de manipulação. Se o Handled for definida como true na TouchDown não gerar o evento, a lógica de manipulação manipulação de eventos. A ilustração a seguir mostra a relação entre os eventos de toque e eventos de manipulação.
Toque e a manipulação de eventos
A lista a seguir descreve a relação entre os eventos de toque e a manipulação é mostrado na ilustração anterior.
Quando o primeiro dispositivo de toque gera um TouchDown evento em um UIElement, as chamadas de lógica de manipulação a CaptureTouch método, que gera a GotTouchCapture evento.
Quando o GotTouchCapture ocorre, as chamadas de lógica de manipulação de Manipulation.AddManipulator método, que gera a ManipulationStarting evento.
Quando o TouchMove eventos ocorrem, a lógica de manipulação gera a ManipulationDelta eventos que ocorrem antes do ManipulationInertiaStarting evento.
Quando o último dispositivo de toque elemento eleva o TouchUp a lógica de manipulação de evento, gera a ManipulationInertiaStarting evento.
Focus
Há dois principais conceitos que pertencem ao foco na WPF: o foco do teclado e foco lógico.
Keyboard Focus
Keyboard focus refers to the element that is receiving keyboard input. There can be only one element on the whole desktop that has keyboard focus. In WPF, the element that has keyboard focus will have IsKeyboardFocused set to true. The static Keyboard method FocusedElement returns the element that currently has keyboard focus.
Keyboard focus can be obtained by tabbing to an element or by clicking the mouse on certain elements, such as a TextBox. Keyboard focus can also be obtained programmatically by using the Focus method on the Keyboard class. Focustenta dar o foco de teclado do elemento especificado. The element returned by Focus is the element that currently has keyboard focus.
In order for an element to obtain keyboard focus the Focusable property and the IsVisible properties must be set to true. Some classes, such as Panel, have Focusable set to false by default; therefore, you may have to set this property to true if you want that element to be able to obtain focus.
The following example uses Focus to set keyboard focus on a Button. The recommended place to set initial focus in an application is in the Loaded event handler.
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
private void OnLoaded(object sender, RoutedEventArgs e)
{
// Sets keyboard focus on the first Button in the sample.
Keyboard.Focus(firstButton);
}
For more information about keyboard focus, see Visão geral sobre Foco.
Logical Focus
Logical focus refers to the FocusManager.FocusedElement in a focus scope. There can be multiple elements that have logical focus in an application, but there may only be one element that has logical focus in a particular focus scope.
A focus scope is a container element that keeps track of the FocusedElement within its scope. When focus leaves a focus scope, the focused element will lose keyboard focus but will retain logical focus. When focus returns to the focus scope, the focused element will obtain keyboard focus. This allows for keyboard focus to be changed between multiple focus scopes but insures that the focused element within the focus scope remains the focused element when focus returns.
Um elemento pode ser transformado em um escopo de foco em Extensible Application Markup Language (XAML) , definindo a FocusManager anexado a propriedade IsFocusScope para true, ou no código, definindo a propriedade anexada usando o SetIsFocusScope método.
The following example makes a StackPanel into a focus scope by setting the IsFocusScope attached property.
<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>
Dim focuseScope2 As New StackPanel()
FocusManager.SetIsFocusScope(focuseScope2, True)
StackPanel focuseScope2 = new StackPanel();
FocusManager.SetIsFocusScope(focuseScope2, true);
Classes in WPF which are focus scopes by default are Window, Menu, ToolBar, and ContextMenu.
An element that has keyboard focus will also have logical focus for the focus scope it belongs to; therefore, setting focus on an element with the Focus method on the Keyboard class or the base element classes will attempt to give the element keyboard focus and logical focus.
To determine the focused element in a focus scope, use GetFocusedElement. To change the focused element for a focus scope, use SetFocusedElement.
For more information about logical focus, see Visão geral sobre Foco.
Mouse Position
The WPF input API provides helpful information with regard to coordinate spaces. For example, coordinate (0,0) is the upper-left coordinate, but the upper-left of which element in the tree? The element that is the input target? The element you attached your event handler to? Or something else? To avoid confusion, the WPF input API requires that you specify your frame of reference when you work with coordinates obtained through the mouse. O GetPosition método retorna a coordenada do ponteiro do mouse em relação ao elemento especificado.
Mouse Capture
Mouse devices specifically hold a modal characteristic known as mouse capture. Mouse capture is used to maintain a transitional input state when a drag-and-drop operation is started, so that other operations involving the nominal on-screen position of the mouse pointer do not necessarily occur. During the drag, the user cannot click without aborting the drag-and-drop, which makes most mouseover cues inappropriate while the mouse capture is held by the drag origin. The input system exposes APIs that can determine mouse capture state, as well as APIs that can force mouse capture to a specific element, or clear mouse capture state. For more information on drag-and-drop operations, see Visão geral sobre arrastar e soltar.
Commands
Commands enable input handling at a more semantic level than device input. Commands are simple directives, such as Cut, Copy, Paste, or Open. Commands are useful for centralizing your command logic. The same command might be accessed from a Menu, on a ToolBar, or through a keyboard shortcut. Commands also provide a mechanism for disabling controls when the command becomes unavailable.
RoutedCommand is the WPF implementation of ICommand. When a RoutedCommand is executed, a PreviewExecuted and an Executed event are raised on the command target, which tunnel and bubble through the element tree like other input. If a command target is not set, the element with keyboard focus will be the command target. The logic that performs the command is attached to a CommandBinding. When an Executed event reaches a CommandBinding for that specific command, the ExecutedRoutedEventHandler on the CommandBinding is called. This handler performs the action of the command.
For more information on commanding, see Visão geral de Comando.
WPF provides a library of common commands which consists of ApplicationCommands, MediaCommands, ComponentCommands, NavigationCommands, and EditingCommands, or you can define your own.
The following example shows how to set up a MenuItem so that when it is clicked it will invoke the Paste command on the TextBox, assuming the TextBox has keyboard focus.
<StackPanel>
<Menu>
<MenuItem Command="ApplicationCommands.Paste" />
</Menu>
<TextBox />
</StackPanel>
' 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
// 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;
Para obter mais informações sobre os comandos em WPF, consulte Visão geral de Comando.
The Input System and Base Elements
Input events such as the attached events defined by the Mouse, Keyboard, and Stylus classes are raised by the input system and injected into a particular position in the object model based on hit testing the visual tree at run time.
Each of the events that Mouse, Keyboard, and Stylus define as an attached event is also re-exposed by the base element classes UIElement and ContentElement as a new routed event. The base element routed events are generated by classes handling the original attached event and reusing the event data.
When the input event becomes associated with a particular source element through its base element input event implementation, it can be routed through the remainder of an event route that is based on a combination of logical and visual tree objects, and be handled by application code. Generally, it is more convenient to handle these device-related input events using the routed events on UIElement and ContentElement, because you can use more intuitive event handler syntax both in XAML and in code. Você pode escolher manipular o evento anexado que iniciou o processo em vez disso, mas você enfrenta diversos problemas: o evento anexado pode estar marcado manipulado pelo tratamento de classe elemento base e você precisará usar os métodos acessadores em vez da sintaxe do evento true para anexar manipuladores para eventos anexados.
What's Next
You now have several techniques to handle input in WPF. You should also have an improved understanding of the various types of input events and the routed event mechanisms used by WPF.
Additional resources are available that explain WPF framework elements and event routing in more detail. Consulte as seguintes visões gerais para obter mais informações, Visão geral de Comando, Visão geral sobre Foco, Visão geral sobre elementos base, Árvores em WPF, e Visão geral sobre eventos roteados.
Consulte também
Conceitos
Visão geral sobre eventos roteados
Visão geral sobre elementos base