Compartir a través de


Introducción a eventos y eventos enrutados

Las APIs importantes

Se describe el concepto de programación de eventos en una aplicación de Windows Runtime, cuando se usa XAML para la definición de la interfaz de usuario. Puedes asignar controladores para eventos como parte de las declaraciones de elementos de la interfaz de usuario en XAML, o puedes agregar los controladores en el código. Windows Runtime admite eventos enrutados: determinados eventos de entrada y eventos de datos se pueden controlar mediante objetos más allá del objeto que desencadenó el evento. Los eventos enrutados son útiles al definir plantillas de control o usar páginas o contenedores de diseño.

Eventos como concepto de programación

Por lo general, los conceptos de eventos al programar una aplicación de Windows Runtime son similares al modelo de eventos en los lenguajes de programación más populares. Si ya sabe cómo trabajar con eventos de Microsoft .NET o C++, tiene una ventaja. Pero no es necesario saber mucho sobre los conceptos del modelo de eventos para realizar algunas tareas básicas, como adjuntar controladores.

Cuando creas una aplicación WinUI (o UWP), la interfaz de usuario se define en marcado (XAML). En la sintaxis de marcado XAML, algunos de los principios de conexión de eventos entre elementos de marcado y entidades de código en tiempo de ejecución son similares a otras tecnologías web, como ASP.NET o HTML5.

Nota:

El código que proporciona la lógica en tiempo de ejecución para una interfaz de usuario definida por XAML se conoce a menudo como código subyacente o el archivo de código subyacente. En las vistas de la solución de Microsoft Visual Studio, esta relación se muestra gráficamente, con el archivo de código subyacente siendo un archivo dependiente y anidado frente a la página XAML a la que hace referencia.

Button.Click: una introducción a los eventos y XAML

Una de las tareas de programación más comunes para una aplicación de Windows Runtime es capturar la entrada del usuario en la interfaz de usuario. Por ejemplo, la interfaz de usuario podría tener un botón en el que el usuario debe hacer clic para enviar información o cambiar el estado.

La interfaz de usuario de la aplicación de Windows Runtime se define mediante la generación de XAML. Este XAML suele ser la salida de una superficie de diseño en Visual Studio. También puedes escribir el XAML en un editor de texto sin formato o en un editor XAML de terceros. Al generar ese XAML, puedes conectar controladores de eventos para elementos de interfaz de usuario individuales al mismo tiempo que defines todos los demás atributos XAML que establecen valores de propiedad de ese elemento de interfaz de usuario.

Para conectar los eventos en XAML, especifique el nombre de forma de cadena del método de controlador que ya ha definido o definirá más adelante en el código subyacente. Por ejemplo, este XAML define un objeto Button con otras propiedades (atributo x:Name, Content) asignadas como atributos y conectan un controlador para el evento Click del botón haciendo referencia a un método denominado ShowUpdatesButton_Click:

<Button x:Name="showUpdatesButton"
  Content="{Binding ShowUpdatesText}"
  Click="ShowUpdatesButton_Click"/>

Sugerencia

El cableado de eventos es un término de programación. Hace referencia al proceso o código en el que se indica que las apariciones de un evento deben invocar un método de controlador con nombre. En la mayoría de los modelos de código de procedimientos, el cableado de eventos es código implícito o explícito "AddHandler" que asigna nombres tanto al evento como al método, y normalmente implica una instancia de objeto de destino. En XAML, "AddHandler" es implícito y el cableado de eventos consiste en asignar un nombre completo al evento como el nombre de atributo de un elemento de objeto y asignar un nombre al controlador como valor de ese atributo.

Escribes el controlador real en el lenguaje de programación que estás usando para todo el código y el código subyacente de la aplicación. Con el atributo Click="ShowUpdatesButton_Click", ha creado un contrato que cuando el XAML está compilado y analizado, tanto el paso de compilación de marcado XAML en la acción de compilación del IDE como el eventual análisis de XAML cuando la aplicación se carga puede encontrar un método llamado ShowUpdatesButton_Click como parte del código de la aplicación. ShowUpdatesButton_Click debe ser un método que implemente una firma de método compatible (basada en un delegado) para cualquier controlador del evento Click . Por ejemplo, este código define el ShowUpdatesButton_Click controlador.

private void ShowUpdatesButton_Click (object sender, RoutedEventArgs e) 
{
    Button b = sender as Button;
    //more logic to do here...
}
Private Sub ShowUpdatesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim b As Button = CType(sender, Button)
    '  more logic to do here...
End Sub
void winrt::MyNamespace::implementation::BlankPage::ShowUpdatesButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e)
{
    auto b{ sender.as<Windows::UI::Xaml::Controls::Button>() };
    // More logic to do here.
}
void MyNamespace::BlankPage::ShowUpdatesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) 
{
    Button^ b = (Button^) sender;
    //more logic to do here...
}

En este ejemplo, el ShowUpdatesButton_Click método se basa en el delegado RoutedEventHandler . Sabrá que este es el delegado que se va a usar porque verá ese delegado denominado en la sintaxis del método Click .

Sugerencia

Visual Studio proporciona una manera cómoda de asignar un nombre al controlador de eventos y definir el método de controlador mientras editas XAML. Al proporcionar el nombre de atributo del evento en el editor de texto XAML, espere un momento hasta que se muestre una lista de Microsoft IntelliSense. Si hace clic en <Nuevo controlador> de eventos de la lista, Microsoft Visual Studio sugerirá un nombre de método basado en el x:Name (o nombre de tipo) del elemento, el nombre del evento y un sufijo numérico. A continuación, puede hacer clic con el botón derecho en el nombre del controlador de eventos seleccionado y hacer clic en Navegar al controlador de eventos. Esto te llevará directamente a la definición del controlador de eventos recién agregado en la vista del editor de código de tu archivo de código subyacente para la página XAML. El controlador de eventos ya tiene la firma correcta, incluido el parámetro sender y la clase de datos de eventos que usa el evento. Además, si ya existe un método de manejador con la firma correcta en el código subyacente, el nombre del método aparece en la lista desplegable de autocompletado junto con la <opción Nuevo manejador de eventos>. También puede presionar la tecla Tab como acceso directo en lugar de hacer clic en los elementos de lista de IntelliSense.

Definición de un controlador de eventos

Para los objetos que son elementos de la interfaz de usuario y declarados en XAML, el código del controlador de eventos se define en la clase parcial que actúa como código subyacente para una página XAML. Los controladores de eventos son métodos que escribes como parte de la clase parcial asociada a tu XAML. Estos controladores de eventos se basan en los delegados que usa un evento determinado. Los métodos del controlador de eventos pueden ser públicos o privados. El acceso privado funciona porque el controlador y la instancia creados por el XAML se unen en última instancia mediante la generación de código. En general, se recomienda que los métodos del controlador de eventos sean privados en la clase .

Nota:

Los controladores de eventos para C++ no se definen en clases parciales, se declaran en el encabezado como miembro de clase privada. Las acciones de compilación de un proyecto de C++ se encargan de generar código que admita el sistema de tipos XAML y el modelo de código subyacente para C++.

Parámetro del remitente y datos de eventos

El controlador que escriba para el evento puede tener acceso a dos valores que están disponibles como entrada para cada caso en el que se invoca el controlador. El primer valor de este tipo es sender, que es una referencia al objeto donde está asociado el controlador. El parámetro sender se escribe como el tipo de objeto base. Una técnica común consiste en convertir el remitente a un tipo más preciso. Esta técnica es útil si espera comprobar o cambiar el estado en el propio objeto remitente . Según el diseño de su aplicación, normalmente conoce un tipo al que es seguro convertir el sender, basado en dónde está asociado el manejador u otros detalles de diseño.

El segundo valor es los datos de eventos, que generalmente aparecen en las definiciones de sintaxis como parámetro e (o args). Puede detectar qué propiedades de los datos de eventos están disponibles examinando el parámetro e del delegado asignado para el evento específico que está controlando y, a continuación, mediante IntelliSense o el Examinador de objetos en Visual Studio. O bien, puedes usar la documentación de referencia de Windows Runtime.

Para algunos eventos, los valores de propiedad específicos de los datos del evento son tan importantes como saber que se produjo el evento. Esto es especialmente cierto de los eventos de entrada. En el caso de eventos de puntero, podría ser importante la posición del puntero cuando se produjo el evento. Para los eventos de teclado, todas las teclas posibles activan un evento KeyDown y KeyUp . Para determinar qué tecla ha presionado un usuario, debe tener acceso a KeyRoutedEventArgs que está disponible para el controlador de eventos. Para obtener más información sobre el control de eventos de entrada, consulta Interacciones de teclado y Controlador de entrada de puntero. Los eventos de entrada y los escenarios de entrada suelen tener consideraciones adicionales que no se tratan en este tema, como la captura de puntero para eventos de puntero y las teclas modificadoras y los códigos de clave de plataforma para eventos de teclado.

Controladores de eventos que usan el patrón asincrónico

En algunos casos, querrá usar las API que usan un patrón asincrónico dentro de un controlador de eventos. Por ejemplo, puede usar un botón en una barra de aplicaciones para mostrar un selector de archivos e interactuar con él. Sin embargo, muchas de las API del selector de archivos son asincrónicas. Deben llamarse dentro de un ámbito asincrónico/await, y el compilador aplicará esto. Por lo tanto, lo que puede hacer es agregar la palabra clave async al controlador de eventos de forma que el controlador ahora sea asyncvoid. Ahora el controlador de eventos puede realizar llamadas asincrónicas o esperadas.

Adición de controladores de eventos en el código

XAML no es la única manera de asignar un controlador de eventos a un objeto . Para agregar controladores de eventos a cualquier objeto determinado en el código, incluidos los objetos que no se pueden usar en XAML, puedes usar la sintaxis específica del lenguaje para agregar controladores de eventos.

En C#, la sintaxis es usar el += operador . Para registrar el controlador, haga referencia al nombre del método del controlador de eventos en el lado derecho del operador.

Si usa código para agregar controladores de eventos a objetos que aparecen en la interfaz de usuario en tiempo de ejecución, una práctica habitual es agregar estos controladores en respuesta a un evento de duración de objeto o devolución de llamada, como Loaded o OnApplyTemplate, de modo que los controladores de eventos del objeto pertinente estén listos para eventos iniciados por el usuario en tiempo de ejecución. En este ejemplo se muestra un esquema XAML de la estructura de página y, a continuación, se proporciona la sintaxis del lenguaje C# para agregar un controlador de eventos a un objeto .

<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">
  <StackPanel>
    <TextBlock Name="textBlock1">Put the pointer over this text</TextBlock>
...
  </StackPanel>
</Grid>
void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += textBlock1_PointerEntered;
    textBlock1.PointerExited += textBlock1_PointerExited;
}

Nota:

Existe una sintaxis más detallada. En 2005, C# agregó una característica denominada inferencia de delegado, que permite a un compilador deducir la nueva instancia de delegado y habilita la sintaxis anterior y más sencilla. La sintaxis detallada es funcionalmente idéntica al ejemplo anterior, pero crea explícitamente una nueva instancia de delegado antes de registrarla, por lo que no aprovecha la inferencia de delegados. Esta sintaxis explícita es menos común, pero es posible que todavía la vea en algunos ejemplos de código.

void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += new PointerEventHandler(textBlock1_PointerEntered);
    textBlock1.PointerExited += new MouseEventHandler(textBlock1_PointerExited);
}

Hay dos posibilidades para la sintaxis de Visual Basic. Una es paralelizar la sintaxis de C# y asignar manejadores directamente a instancias. Esto requiere la palabra clave AddHandler y también el operador AddressOf que desreferencia el nombre del método del controlador.

La otra opción para la sintaxis de Visual Basic es usar la palabra clave Handles en controladores de eventos. Esta técnica es adecuada para los casos en los que se espera que existan controladores en objetos en tiempo de carga y persistan durante toda la duración del objeto. El uso de identificadores en un objeto definido en XAML requiere que proporciones un nombre / x:Name. Este nombre se convierte en el calificador de instancia necesario para la parte Instance.Event de la sintaxis Handles . En este caso, no necesita un controlador de eventos basado en la duración del objeto para iniciar la asociación de los otros controladores de eventos; las conexiones Handles se crean al compilar la página XAML.

Private Sub textBlock1_PointerEntered(ByVal sender As Object, ByVal e As PointerRoutedEventArgs) Handles textBlock1.PointerEntered
' ...
End Sub

Nota:

Visual Studio y su superficie de diseño XAML suelen promover la técnica de control de instancias en lugar de la palabra clave Handles . Esto se debe a que establecer el cableado del controlador de eventos en XAML forma parte del flujo de trabajo típico diseñador-desarrollador, y la técnica de la palabra clave Handles no es compatible con el cableado de los controladores de eventos en XAML.

En C++/CX, también se usa la += sintaxis, pero hay diferencias con respecto al formulario básico de C#:

  • No existe ninguna inferencia de delegado, por lo que debe usar ref new para la instancia de delegado.
  • El constructor delegado tiene dos parámetros y requiere el objeto de destino como primer parámetro. Normalmente, se especifica esto.
  • El constructor delegado requiere la dirección del método como segundo parámetro, por lo que el operador & reference precede al nombre del método.
textBlock1().PointerEntered({this, &MainPage::TextBlock1_PointerEntered });
textBlock1->PointerEntered += 
ref new PointerEventHandler(this, &BlankPage::textBlock1_PointerEntered);

Eliminación de controladores de eventos en el código

Por lo general, no es necesario eliminar manejadores de eventos en el código, incluso si los has añadido en él. El comportamiento de duración del objeto para la mayoría de los objetos de Windows Runtime, como páginas y controles, destruirá los objetos cuando se desconecten de la ventana principal y su árbol visual, y las referencias de delegado también se destruyen. .NET lo hace a través de la recolección de elementos no utilizados y Windows Runtime con C++/CX usa referencias débiles de forma predeterminada.

Hay algunos casos poco frecuentes en los que desea quitar los controladores de eventos explícitamente. Estos incluyen:

  • Controladores que ha agregado para eventos estáticos, que no se pueden recopilar de forma convencional. Algunos ejemplos de eventos estáticos en la API de Windows Runtime son los eventos de las clases CompositionTarget y Clipboard .
  • Pruebe el código en el que desea que el tiempo de eliminación del controlador sea inmediato o código en el que se intercambian controladores de eventos antiguos o nuevos para un evento en tiempo de ejecución.
  • Implementación de un accesor remove personalizado.
  • Eventos estáticos personalizados.
  • Controladores para las navegaciones de página.

FrameworkElement.Unloaded o Page.NavigatedFrom son posibles desencadenadores de eventos que tienen posiciones adecuadas en la administración de estado y la duración de objetos, de modo que puede usarlos para quitar controladores para otros eventos.

Por ejemplo, puede quitar un controlador de eventos denominado textBlock1_PointerEntered del objeto de destino textBlock1 mediante este código.

textBlock1.PointerEntered -= textBlock1_PointerEntered;
RemoveHandler textBlock1.PointerEntered, AddressOf textBlock1_PointerEntered

También puedes quitar controladores para los casos en los que el evento se agregó a través de un atributo XAML, lo que significa que el controlador se agregó en el código generado. Esto es más fácil de hacer si proporcionó un valor name para el elemento donde se adjuntó el controlador, porque eso proporciona una referencia de objeto para el código más adelante; sin embargo, también puede recorrer el árbol de objetos para encontrar la referencia de objeto necesaria en los casos en los que el objeto no tiene nombre.

Si necesita quitar un controlador de eventos en C++/CX, necesitará un token de registro, que debería haber recibido del valor devuelto del registro del += controlador de eventos. Esto se debe a que el valor que se utiliza para el lado derecho de la -= cancelación de registro, según la sintaxis de C++/CX, es el token, no el nombre del método. Para C++/CX, no puedes quitar controladores que se agregaron como un atributo XAML porque el código generado de C++/CX no guarda un token.

Eventos enrutados

Windows Runtime admite el concepto de un evento enrutado para un conjunto de eventos presentes en la mayoría de los elementos de la interfaz de usuario. Estos eventos son para escenarios de entrada e interacción del usuario, y se implementan en la clase base UIElement . Esta es una lista de eventos de entrada que son eventos enrutados:

Un evento enrutado es un evento que puede pasarse (enrutado) de un objeto secundario a cada uno de sus objetos primarios sucesivos en un árbol de objetos. La estructura XAML de la interfaz de usuario se aproxima a este árbol, con la raíz de ese árbol que es el elemento raíz en XAML. El árbol de objetos verdadero puede variar ligeramente con respecto al anidamiento de elementos XAML, ya que el árbol de objetos no incluye características del lenguaje XAML, como etiquetas de elementos de propiedad. Puedes concebir el evento enrutado como burbujeo desde cualquier elemento hijo de un objeto XAML que active el evento, hacia el objeto padre que lo contiene. El evento y sus datos de eventos se pueden controlar en varios objetos a lo largo de la ruta del evento. Si ningún elemento tiene controladores, la ruta podría seguir hasta que se alcance el elemento raíz.

Si conoce tecnologías web como HTML dinámico (DHTML) o HTML5, es posible que ya esté familiarizado con el concepto de evento de burbujeo.

Cuando un evento enrutado se propaga a través de su ruta de eventos, todos los controladores de eventos adjuntos acceden a una instancia compartida de datos de eventos. Por lo tanto, si un controlador puede escribir cualquiera de los datos del evento, los cambios realizados en los datos de eventos se pasarán al siguiente controlador y es posible que ya no representen los datos de evento originales del evento. Cuando un evento tiene un comportamiento de evento enrutado, la documentación de referencia incluirá comentarios u otras notaciones sobre el comportamiento enrutado.

Propiedad OriginalSource de RoutedEventArgs

Cuando un evento propaga una ruta de eventos, el remitente ya no es el mismo objeto que el objeto de generación de eventos. En su lugar, sender es el objeto donde se adjunta el controlador que se está invocando.

En algunos casos, el remitente no es interesante y, en su lugar, está interesado en información como cuál de los posibles objetos secundarios que el puntero está sobre cuando se desencadena un evento de puntero, o qué objeto en una interfaz de usuario mayor mantiene el foco cuando un usuario presiona una tecla de teclado. En estos casos, puede usar el valor de la propiedad OriginalSource . En todos los puntos de la ruta, OriginalSource informa del objeto original que desencadenó el evento, en lugar del objeto donde está asociado el controlador. Sin embargo, para los eventos de entrada UIElement , ese objeto original suele ser un objeto que no es visible inmediatamente en el XAML de definición de interfaz de usuario de nivel de página. En su lugar, ese objeto de origen original podría ser una parte de plantilla de un control. Por ejemplo, si el usuario mantiene el puntero sobre el borde de un botón, para la mayoría de los eventos de puntero, OriginalSource es una parte de la plantilla Borde de la plantilla, no el propio botón .

Consejo La propagación de eventos de entrada es especialmente útil si está creando un control con plantilla. Cualquier control que tenga una plantilla puede tener una nueva plantilla aplicada por su consumidor. El consumidor que intenta volver a crear una plantilla de trabajo podría eliminar involuntariamente algún control de eventos declarado en la plantilla predeterminada. Todavía puede proporcionar el manejo de eventos a nivel de control asociando manejadores como parte de la sobrescritura OnApplyTemplate en la definición de la clase. A continuación, puede detectar los eventos de entrada que se propagan hasta la raíz del control en la instanciación.

Propiedad Handled

Varias clases de datos de eventos para eventos enrutados específicos contienen una propiedad denominada Handled. Para obtener ejemplos, vea PointerRoutedEventArgs.Handled, KeyRoutedEventArgs.Handled, DragEventArgs.Handled. En todos los casos Handled es una propiedad booleana que se puede establecer.

Establecer la propiedad Handled en true influye en el comportamiento del sistema de eventos. Cuando Handled es true, el enrutamiento se detiene para la mayoría de los controladores de eventos; El evento no continúa a lo largo de la ruta para notificar a otros controladores adjuntos de ese caso de evento en particular. Lo que significa "controlado" en el contexto del evento y cómo responde su aplicación depende de usted. Básicamente, Handled es un protocolo simple que permite al código de la aplicación indicar que la ocurrencia de un evento no necesita propagarse a ningún contenedor, ya que la lógica de tu aplicación se ha ocupado de lo que se necesita hacer. Por el contrario, debe tener cuidado de no manejar eventos que probablemente deban propagarse para que los comportamientos integrados del sistema o del control puedan actuar. Por ejemplo, manejar eventos de bajo nivel dentro de los componentes o elementos de un control de selección puede ser perjudicial. Es posible que el control de selección busque eventos de entrada para saber que la selección debe cambiar.

No todos los eventos enrutados pueden cancelar una ruta de esta manera, y puede saberlo porque no tendrán una propiedad Handled. Por ejemplo, GotFocus y LostFocus hacen burbujas, pero siempre se propagan hasta la raíz y sus clases de datos de eventos no tienen una propiedad Handled que pueda influir en ese comportamiento.

Controladores de eventos de entrada en los controles

Los controles específicos de Windows Runtime a veces usan el concepto handled para los eventos de entrada internamente. Esto puede hacer que parezca que nunca se produce un evento de entrada, ya que el código de usuario no puede controlarlo. Por ejemplo, la clase Button incluye lógica que controla deliberadamente el evento de entrada general PointerPressed. Esto se debe a que los botones activan un evento Click iniciado por la entrada presionada por puntero, así como por otros modos de entrada, como controlar teclas como la tecla Entrar que puede invocar el botón cuando se centra. Con respecto al diseño de la clase Button, el evento de entrada bruto se gestiona conceptualmente y los consumidores de clase, como su código de usuario, pueden interactuar con el evento Click relevante para el control. Los temas para clases de control específicas en la referencia de la API de Windows Runtime a menudo anoten el comportamiento de control de eventos que implementa la clase. En algunos casos, puede cambiar el comportamiento reemplazando los métodos OnEvent . Por ejemplo, puede cambiar cómo reacciona la clase derivada de TextBox a la entrada de clave reemplazando Control.OnKeyDown.

Registro de controladores para eventos enrutados ya controlados

Anteriormente dijimos que configurar Handled a true impide que se llame a la mayoría de los controladores. Pero el método AddHandler proporciona una técnica en la que puede adjuntar un controlador que siempre se invoca para la ruta, incluso si algún otro controlador anterior en la ruta ha establecido Handled en true en los datos de eventos compartidos. Esta técnica es útil si un control que está utilizando ha gestionado el evento en su composición interna o para lógica específica del control. pero aún desea responder a ella desde una instancia de control o desde la interfaz de usuario de la aplicación. Pero use esta técnica con precaución, ya que puede contradecir el propósito de Handled y posiblemente interrumpir las interacciones deseadas de un control.

Solo los eventos enrutados que tienen un identificador de evento enrutado correspondiente pueden usar la técnica de control de eventos AddHandler , ya que el identificador es una entrada necesaria del método AddHandler . Consulte la documentación de referencia de AddHandler para obtener una lista de eventos que tienen identificadores de eventos enrutados disponibles. En la mayor parte, esta es la misma lista de eventos enrutados que le mostramos anteriormente. La excepción es que las dos últimas de la lista: GotFocus y LostFocus no tienen un identificador de evento enrutado, por lo que no puede usar AddHandler para ellos.

Eventos enrutados fuera del árbol visual

Algunos objetos participan en una relación con el árbol visual principal que es conceptualmente similar a tener una superposición sobre los objetos visuales principales. Estos objetos no forman parte de las relaciones habituales entre elementos primarios y secundarios que conectan todos los elementos de árbol a la raíz visual. Este es el caso de cualquier elemento emergente o información sobre herramientas que se muestre. Si desea manejar eventos enrutados desde un elemento emergente o ventana emergente, coloque los controladores en elementos de interfaz de usuario específicos que se encuentran dentro del elemento emergente o ventana emergente y no en los elementos elemento emergente o ventana emergente en sí mismos. No confíe en el enrutamiento dentro de cualquier composición que se lleve a cabo para Popup o ToolTip. Esto se debe a que el enrutamiento de eventos enrutados solo funciona a través del árbol visual principal. Una información emergente o una información sobre herramientas no se considera un padre de elementos de interfaz de usuario subordinados y nunca recibe el evento enrutado, incluso si intenta utilizar algo como el fondo predeterminado Popup como área de captura para eventos de entrada.

Pruebas de impacto y eventos de entrada

Determinar si un elemento es visible para las entradas del mouse, el tacto y el lápiz óptico en la interfaz de usuario, y dónde, se denomina prueba de impacto. Para las acciones táctiles y también para los eventos específicos de interacción o manipulación que son consecuencias de una acción táctil, un elemento debe ser visible para las pruebas de contacto para poder ser la fuente del evento y activar el evento asociado a la acción. De lo contrario, la acción pasa a través del elemento hacia los elementos subyacentes o elementos padres en el árbol visual que podrían interactuar con esa entrada. Hay varios factores que afectan a las pruebas de impacto, pero puede determinar si un elemento dado puede desencadenar eventos de entrada comprobando su propiedad IsHitTestVisible. Esta propiedad devuelve true solo si el elemento cumple estos criterios:

  • El valor de la propiedad Visibility del elemento es Visible.
  • El valor de la propiedad Background o Fill del elemento no es null. Un valor nullBrush resulta en transparencia e invisibilidad para la prueba de colisión. (Para que un elemento sea transparente, pero que también se pueda probar, use un pincel transparente en lugar de null).

NotaEl fondo y el relleno no se definen mediante UIElement y, en su lugar, se definen mediante diferentes clases derivadas, como Control y Forma. Pero las implicaciones de los pinceles que se usan para las propiedades en primer plano y en segundo plano son las mismas para las pruebas de posicionamiento y los eventos de entrada, independientemente de qué subclase implemente las propiedades.

  • Si el elemento es un control, su valor de propiedad IsEnabled debe ser true.
  • El elemento debe tener dimensiones reales en el diseño. Un elemento donde ActualHeight y ActualWidth son 0 no desencadenarán eventos de entrada.

Algunos controles tienen reglas especiales para las pruebas de impacto. Por ejemplo, TextBlock no tiene ninguna propiedad Background , pero todavía se puede probar en toda la región de sus dimensiones. Los controles Image y MediaElement se pueden probar a través de sus dimensiones de rectángulo definidas, independientemente del contenido transparente, como el canal alfa en el archivo de origen multimedia que se muestra. Los controles WebView tienen un comportamiento especial de prueba de detección porque la entrada puede ser gestionada por el HTML hospedado y disparar eventos de scripts.

La mayoría de las clases Panel y Border no son detectables por pruebas de colisión en su propio fondo de pantalla, pero aún pueden manejar los eventos de entrada de usuario que se enrutan desde los elementos que contienen.

Puede determinar qué elementos se encuentran en la misma posición que un evento de entrada de usuario, independientemente de si los elementos se pueden probar. Para ello, llame al método FindElementsInHostCoordinates . Como indica el nombre, este método busca los elementos en una ubicación relativa a un elemento host especificado. Sin embargo, las transformaciones aplicadas y los cambios de diseño pueden ajustar el sistema de coordenadas relativo de un elemento y, por tanto, afectar a qué elementos se encuentran en una ubicación determinada.

Comando

Un pequeño número de elementos de la interfaz de usuario admiten comandos. El comando usa eventos enrutados relacionados con la entrada en su implementación subyacente y permite el procesamiento de la entrada de interfaz de usuario relacionada (una determinada acción de puntero, una tecla de aceleración específica) invocando un único controlador de comandos. Si el comando está disponible para un elemento de interfaz de usuario, considere la posibilidad de usar sus API de comandos en lugar de cualquier evento de entrada discreto. Normalmente, se usa una referencia de Binding en las propiedades de una clase que define el modelo de vista para los datos. Las propiedades contienen comandos con nombre que implementan el patrón de comandos ICommand específico del lenguaje. Para obtener más información, consulta ButtonBase.Command.

Eventos personalizados en Windows Runtime

Para definir eventos personalizados, la forma de agregar el evento y lo que significa para el diseño de clase depende en gran medida del lenguaje de programación que use.

  • Para C# y Visual Basic, va a definir un evento CLR. Puede usar el patrón de eventos estándar de .NET, siempre que no use descriptores de acceso personalizados (agregue/remove). Sugerencias adicionales:
  • Para C++/CX, vea Eventos (C++/CX).
    • Use referencias con nombre incluso para sus propios usos de eventos personalizados. No use lambda para eventos personalizados, puede crear una referencia circular.

No puedes declarar un evento enrutado personalizado para Windows Runtime; Los eventos enrutados se limitan al conjunto que procede de Windows Runtime.

La definición de un evento personalizado normalmente se realiza como parte del ejercicio de definir un control personalizado. Es un patrón común tener una propiedad de dependencia que tenga una devolución de llamada modificada por propiedades y también definir un evento personalizado que se desencadena mediante la devolución de llamada de la propiedad de dependencia en algunos o todos los casos. Los consumidores de su control no tienen acceso a la devolución de llamada para propiedades modificadas que usted definió, pero tener un evento de notificación disponible es la siguiente mejor alternativa. Para obtener más información, consulte Propiedades de dependencia personalizadas.