Extensión de marcado {x:Bind}

Nota Para obtener información general sobre el uso del enlace de datos en la aplicación con {x:Bind} (y para obtener una comparación completa entre {x:Bind} y {Binding}), consulta Enlace de datos en profundidad.

La extensión de marcado {x:Bind} (nueva para Windows 10) es una alternativa a {Binding}. {x:Bind} se ejecuta en menos tiempo y menos memoria que {Binding} y admite una mejor depuración.

En tiempo de compilación XAML, {x:Bind} se convierte en código que obtendrá un valor de una propiedad en un origen de datos y lo establecerá en la propiedad especificada en el marcado. El objeto de enlace se puede configurar opcionalmente para observar los cambios en el valor de la propiedad del origen de datos y actualizarse en función de esos cambios (Mode="OneWay"). También se puede configurar opcionalmente para insertar cambios en su propio valor en la propiedad de origen (Mode="TwoWay").

Los objetos de enlace creados por {x: enlace} y {Binding} son prácticamente funcionalmente equivalentes. Pero {x:Bind} ejecuta código de propósito especial, que genera en tiempo de compilación y {Binding} usa la inspección de objetos en tiempo de ejecución de uso general. Por lo tanto, los enlaces {x:Bind} (a menudo denominados enlaces compilados) tienen un gran rendimiento, proporcionan una validación en tiempo de compilación de las expresiones de enlace y admiten la depuración al permitirle establecer puntos de interrupción en los archivos de código que se generan como la clase parcial de la página. Estos archivos pueden encontrarse en la carpeta obj, con nombres como (para C#) <view name>.g.cs.

Sugerencia

{x:Bind} tiene un modo predeterminado de OneTime, a diferencia de {Binding}, que tiene un modo predeterminado de OneWay. Esto se eligió por motivos de rendimiento, ya que el uso de OneWay hace que se genere más código para enlazar y controlar la detección de cambios. Puede especificar explícitamente un modo para usar el enlace oneWay o TwoWay. También puede usar x:DefaultBindMode para cambiar el modo predeterminado de {x:Bind} para un segmento específico del árbol de marcado. El modo especificado se aplica a las expresiones {x:Bind} de ese elemento y sus elementos secundarios, que no especifican explícitamente un modo como parte del enlace.

Aplicaciones de ejemplo que muestran {x:Bind}

Uso del atributo XAML

<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
Término Descripción
propertyPath Cadena que especifica la ruta de acceso de la propiedad para el enlace. A continuación encontrará más información en la sección Ruta de acceso de la propiedad .
bindingProperties
propName=value[, propName=value]* Una o varias propiedades de enlace que se especifican mediante una sintaxis de par nombre-valor.
propName Nombre de cadena de la propiedad que se va a establecer en el objeto de enlace. Por ejemplo, "Converter".
value El valor en el que se establecerá la propiedad. La sintaxis del argumento depende de la propiedad que se establece. Este es un ejemplo de uso de un valor propName=en el que el valor es una extensión de marcado: Converter={StaticResource myConverterClass}. Para obtener más información, consulta la sección Propiedades que puedes establecer con {x:Bind} a continuación.

Ejemplos

<Page x:Class="QuizGame.View.HostView" ... >
    <Button Content="{x:Bind Path=ViewModel.NextButtonText, Mode=OneWay}" ... />
</Page>

En este ejemplo XAML se usa {x:Bind} con una propiedad ListView.ItemTemplate . Tenga en cuenta la declaración de un valor x:DataType .

  <DataTemplate x:Key="SimpleItemTemplate" x:DataType="data:SampleDataGroup">
    <StackPanel Orientation="Vertical" Height="50">
      <TextBlock Text="{x:Bind Title}"/>
      <TextBlock Text="{x:Bind Description}"/>
    </StackPanel>
  </DataTemplate>

Ruta de acceso de la propiedad

PropertyPath establece la ruta de acceso para una expresión {x:Bind} . Path es una ruta de acceso de propiedad que especifica el valor de la propiedad, la subpropia, el campo o el método al que se enlaza (el origen). Puede mencionar el nombre de la propiedad Path explícitamente: {x:Bind Path=...}. O bien, puede omitirlo: {x:Bind ...}.

Resolución de ruta de acceso de propiedad

{x:Bind} no usa DataContext como origen predeterminado; en su lugar, usa la página o el propio control de usuario. Por lo tanto, buscará en el código subyacente de la página o el control de usuario para propiedades, campos y métodos. Para exponer el modelo de vista a {x:Bind}, normalmente querrá agregar nuevos campos o propiedades al código subyacente para la página o el control de usuario. Los pasos de una ruta de acceso de propiedad se delimitan por puntos (.) y puede incluir varios delimitadores para recorrer las subpropiedades sucesivas. Use el delimitador de puntos independientemente del lenguaje de programación utilizado para implementar el objeto al que se enlaza.

Por ejemplo: en una página, Text="{x:Bind Employee.FirstName}" buscará un miembro Employee en la página y, a continuación, un miembro FirstName en el objeto devuelto por Employee. Si va a enlazar un control de elementos a una propiedad que contiene los dependientes de un empleado, la ruta de acceso de la propiedad podría ser "Employee.Dependents" y la plantilla de elemento del control items se ocuparía de mostrar los elementos en "Dependientes".

Para C++/CX, {x:Bind} no se puede enlazar a campos y propiedades privados en la página o el modelo de datos; tendrá que tener una propiedad pública para que se pueda enlazar. El área expuesta para el enlace debe exponerse como clases o interfaces CX para que podamos obtener los metadatos pertinentes. El atributo [Bindable] no debe ser necesario.

Con x:Bind, no es necesario usar ElementName=xxx como parte de la expresión de enlace. En su lugar, puede usar el nombre del elemento como la primera parte de la ruta de acceso para el enlace porque los elementos con nombre se convierten en campos dentro de la página o el control de usuario que representa el origen del enlace raíz.

Colecciones

Si el origen de datos es una colección, una ruta de acceso de propiedad puede especificar elementos de la colección por su posición o índice. Por ejemplo, "Teams[0]. Reproductores", donde el literal "[]" incluye el "0" que solicita el primer elemento de una colección indizada con cero.

Para usar un indexador, el modelo debe implementar IList<T> o IVector<T> en el tipo de la propiedad que se va a indexar. (Tenga en cuenta que IReadOnlyList<T> e IVectorView<T> no admiten la sintaxis del indexador). Si el tipo de la propiedad indizada admite INotifyCollectionChanged o IObservableVector y el enlace es OneWay o TwoWay, se registrará y escuchará las notificaciones de cambio en esas interfaces. La lógica de detección de cambios se actualizará en función de todos los cambios de recopilación, incluso si eso no afecta al valor indexado específico. Esto se debe a que la lógica de escucha es común en todas las instancias de la colección.

Si el origen de datos es un diccionario o un mapa, una ruta de acceso de propiedad puede especificar elementos de la colección por su nombre de cadena. Por ejemplo <, TextBlock Text="{x:Bind Players['John Smith']}" /> buscará un elemento en el diccionario denominado "John Smith". El nombre debe incluirse entre comillas y se pueden usar comillas simples o dobles. Hat (^) se puede usar para escape de comillas en cadenas. Normalmente, es más fácil usar comillas alternativas de las usadas para el atributo XAML. (Tenga en cuenta que IReadOnlyDictionary<T> e IMapView<T> no admiten la sintaxis del indexador).

Para usar un indexador de cadenas, el modelo debe implementar la cadena IDictionary<, la cadena T> o IMap<, T> en el tipo de la propiedad que se va a indexar. Si el tipo de la propiedad indexada admite IObservableMap y el enlace es OneWay o TwoWay, se registrará y escuchará las notificaciones de cambio en esas interfaces. La lógica de detección de cambios se actualizará en función de todos los cambios de recopilación, incluso si eso no afecta al valor indexado específico. Esto se debe a que la lógica de escucha es común en todas las instancias de la colección.

Propiedades asociadas

Para enlazar a las propiedades adjuntas, debe colocar el nombre de clase y propiedad entre paréntesis después del punto. Por ejemplo , Text="{x:Bind Button22.( Grid.Row)}". Si la propiedad no se declara en un espacio de nombres Xaml, tendrás que prefijarla con un espacio de nombres xml, que debes asignar a un espacio de nombres de código en el encabezado del documento.

Conversión

Los enlaces compilados están fuertemente tipados y resolverán el tipo de cada paso de una ruta de acceso. Si el tipo devuelto no tiene el miembro, se producirá un error en tiempo de compilación. Puede especificar una conversión para indicar al enlace el tipo real del objeto.

En el caso siguiente, obj es una propiedad de tipo object, pero contiene un cuadro de texto, por lo que podemos usar text ="{x:Bind ((TextBox)obj). Text}" o Text="{x:Bind obj.(TextBox.Text)}".

El campo groups3 de Text="{x:Bind ((data:SampleDataGroup)groups3[0]). Title}" es un diccionario de objetos, por lo que debe convertirlo a data:SampleDataGroup. Tenga en cuenta el uso de los datos xml : prefijo de espacio de nombres para asignar el tipo de objeto a un espacio de nombres de código que no forma parte del espacio de nombres XAML predeterminado.

Nota: La sintaxis de conversión de estilo C#es más flexible que la sintaxis de propiedad adjunta y es la sintaxis recomendada en el futuro.

Conversión sin ruta de acceso

El analizador de enlace nativo no proporciona una palabra clave para representar this como parámetro de función, pero admite la conversión sin rutas de acceso (por ejemplo, {x:Bind (x:String)}), que se puede usar como parámetro de función. Por lo tanto, {x:Bind MethodName((namespace:TypeOfThis))} es una manera válida de realizar lo que es conceptualmente equivalente a {x:Bind MethodName(this)}.

Ejemplo:

Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}"

<Page
    x:Class="AppSample.MainPage"
    ...
    xmlns:local="using:AppSample">

    <Grid>
        <ListView ItemsSource="{x:Bind Songs}">
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="local:SongItem">
                    <TextBlock
                        Margin="12"
                        FontSize="40"
                        Text="{x:Bind local:MainPage.GenerateSongTitle((local:SongItem))}" />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
namespace AppSample
{
    public class SongItem
    {
        public string TrackName { get; private set; }
        public string ArtistName { get; private set; }

        public SongItem(string trackName, string artistName)
        {
            ArtistName = artistName;
            TrackName = trackName;
        }
    }

    public sealed partial class MainPage : Page
    {
        public List<SongItem> Songs { get; }
        public MainPage()
        {
            Songs = new List<SongItem>()
            {
                new SongItem("Track 1", "Artist 1"),
                new SongItem("Track 2", "Artist 2"),
                new SongItem("Track 3", "Artist 3")
            };

            this.InitializeComponent();
        }

        public static string GenerateSongTitle(SongItem song)
        {
            return $"{song.TrackName} - {song.ArtistName}";
        }
    }
}

Funciones en rutas de acceso de enlace

A partir de la versión 1607 de Windows 10, {x: Bind} admite el uso de una función como el paso hoja de la ruta de acceso de enlace. Se trata de una característica eficaz para el enlace de datos que permite varios escenarios en el marcado. Consulte enlaces de función para obtener más información.

Enlace de eventos

El enlace de eventos es una característica única para el enlace compilado. Permite especificar el controlador para un evento mediante un enlace, en lugar de tener que ser un método en el código subyacente. Por ejemplo: Click="{x:Bind rootFrame.GoForward}".

En el caso de los eventos, el método de destino no debe sobrecargarse y también debe:

  • Coincide con la firma del evento.
  • O no tiene parámetros.
  • O bien, tienen el mismo número de parámetros de tipos que se pueden asignar a partir de los tipos de los parámetros de evento.

En el código subyacente generado, el enlace compilado controla el evento y lo enruta al método en el modelo, evaluando la ruta de acceso de la expresión de enlace cuando se produce el evento. Esto significa que, a diferencia de los enlaces de propiedades, no realiza un seguimiento de los cambios en el modelo.

Para obtener más información sobre la sintaxis de cadena de una ruta de acceso de propiedad, vea Sintaxis de ruta de acceso de propiedad, teniendo en cuenta las diferencias que se describen aquí para {x:Bind}.

Propiedades que puede establecer con {x:Bind}

{x:Bind} se ilustra con la sintaxis de marcador de posición bindingProperties porque hay varias propiedades de lectura y escritura que se pueden establecer en la extensión de marcado. Las propiedades se pueden establecer en cualquier orden con pares de valores propName=separados por comas. Tenga en cuenta que no puede incluir saltos de línea en la expresión de enlace. Algunas de las propiedades requieren tipos que no tienen una conversión de tipos, por lo que requieren extensiones de marcado propias anidadas dentro de {x:Bind}.

Estas propiedades funcionan de la misma manera que las propiedades de la clase Binding.

Propiedad Descripción
Path Consulte la sección Ruta de acceso de la propiedad anterior.
Converter Especifica el objeto de convertidor al que llama el motor de enlace. El convertidor se puede establecer en XAML, pero solo si haces referencia a una instancia de objeto que has asignado en una referencia de extensión de marcado {StaticResource} a ese objeto en el diccionario de recursos.
ConverterLanguage Especifica la referencia cultural que va a usar el convertidor. (Si está estableciendo ConverterLanguage que también debe establecer Converter). La referencia cultural se establece como un identificador basado en estándares. Para obtener más información, consulta ConverterLanguage.
ConverterParameter Especifica el parámetro de convertidor que se puede usar en la lógica del convertidor. (Si está estableciendo ConverterParameter también debe establecer Converter). La mayoría de los convertidores usan lógica simple que obtienen toda la información que necesitan del valor pasado para convertir y no necesitan un valor ConverterParameter . El parámetro ConverterParameter es para implementaciones de convertidores moderadamente avanzadas que tienen más de una lógica que claves de lo que se pasa en ConverterParameter. Puede escribir un convertidor que use valores distintos de cadenas, pero esto no es habitual, consulta Comentarios en ConverterParameter para obtener más información.
FallbackValue Especifica un valor que se va a mostrar cuando no se puede resolver el origen o la ruta de acceso.
Modo Especifica el modo de enlace, como una de estas cadenas: "OneTime", "OneWay" o "TwoWay". El valor predeterminado es "OneTime". Tenga en cuenta que esto difiere del valor predeterminado de {Binding}, que es "OneWay" en la mayoría de los casos.
TargetNullValue Especifica un valor que se va a mostrar cuando el valor de origen se resuelve, pero es explícitamente NULL.
BindBack Especifica una función que se va a usar para la dirección inversa de un enlace bidireccional.
UpdateSourceTrigger Especifica cuándo se deben devolver los cambios del control al modelo en enlaces de TwoWay. El valor predeterminado para todas las propiedades excepto TextBox.Text es PropertyChanged; TextBox.Text es LostFocus.

Nota:

Si va a convertir el marcado de {Binding} a {x:Bind}, tenga en cuenta las diferencias en los valores predeterminados de la propiedad Mode . x:DefaultBindMode se puede usar para cambiar el modo predeterminado de x:Bind para un segmento específico del árbol de marcado. El modo seleccionado aplicará cualquier expresión x:Bind en ese elemento y sus elementos secundarios, que no especifiquen explícitamente un modo como parte del enlace. OneTime es más eficaz que OneWay, ya que el uso de OneWay hará que se genere más código para enlazar y controlar la detección de cambios.

Comentarios

Dado que {x:Bind} usa código generado para lograr sus ventajas, requiere información de tipos en tiempo de compilación. Esto significa que no se puede enlazar a las propiedades en las que no conoce el tipo con antelación. Debido a esto, no se puede usar {x:Bind} con la propiedad DataContext , que es de tipo Object, y también está sujeta a cambios en tiempo de ejecución.

Al usar {x:Bind} con plantillas de datos, debe indicar el tipo al que se enlaza estableciendo un valor x:DataType , como se muestra en la sección Ejemplos . También puede establecer el tipo en un tipo de interfaz o clase base y, a continuación, usar conversiones si es necesario para formular una expresión completa.

Los enlaces compilados dependen de la generación de código. Por lo tanto, si usa {x:Bind} en un diccionario de recursos, el diccionario de recursos debe tener una clase de código subyacente. Consulte Diccionarios de recursos con {x:Bind} para obtener un ejemplo de código.

Las páginas y los controles de usuario que incluyen enlaces compilados tendrán una propiedad "Bindings" en el código generado. Esto incluye los siguientes métodos:

  • Update(): esto actualizará los valores de todos los enlaces compilados. Los enlaces unidireccionales o bidireccionales tendrán los agentes de escucha conectados para detectar cambios.
  • Initialize(): si los enlaces aún no se han inicializado, llamará a Update() para inicializar los enlaces.
  • StopTracking(): se desengancharán todos los agentes de escucha creados para enlaces unidireccionales y bidireccionales. Se pueden volver a inicializar mediante el método Update().

Nota:

A partir de Windows 10, versión 1607, el marco XAML proporciona un convertidor booleano integrado a visibility. El convertidor se asigna true al valor de enumeración Visible y false a Collapsed para que pueda enlazar una propiedad Visibility a un booleano sin crear un convertidor. Tenga en cuenta que esto no es una característica del enlace de funciones, solo el enlace de propiedades. Para usar el convertidor integrado, la versión mínima del SDK de destino de la aplicación debe ser 14393 o posterior. No puedes usarlo si la aplicación está destinada a versiones anteriores de Windows 10. Para obtener más información sobre las versiones de destino, consulta Version adaptive code (Código adaptativo para versiones).

Sugerencia Si necesita especificar una sola llave para un valor, como en Path o ConverterParameter, preceda a una barra diagonal inversa: . \{ Como alternativa, incluya toda la cadena que contiene las llaves que necesitan escape en un conjunto de comillas secundarias, por ejemplo ConverterParameter='{Mix}'.

Converter, ConverterLanguage y ConverterLanguage están relacionados con el escenario de convertir un valor o tipo del origen de enlace en un tipo o valor compatible con la propiedad de destino de enlace. Para obtener más información y ejemplos, consulte la sección "Conversiones de datos" del enlace de datos en profundidad.

{x:Bind} es solo una extensión de marcado, sin ninguna manera de crear o manipular dichos enlaces mediante programación. Para obtener más información sobre las extensiones de marcado, consulta Introducción a XAML.