Parte 4.Part 4. Conceptos básicos del enlace de datosData Binding Basics

Descargar ejemplo Descargar el ejemploDownload Sample Download the sample

Los enlaces de datos permiten vincular las propiedades de dos objetos para que un cambio en uno produzca un cambio en el otro. Se trata de una herramienta muy valiosa y, mientras que los enlaces de datos se pueden definir completamente en el código, XAML proporciona accesos directos y comodidad. Por consiguiente, una de las extensiones de marcado más importantes en Xamarin.Forms es Binding.Data bindings allow properties of two objects to be linked so that a change in one causes a change in the other. This is a very valuable tool, and while data bindings can be defined entirely in code, XAML provides shortcuts and convenience. Consequently, one of the most important markup extensions in Xamarin.Forms is Binding.

Enlaces de datosData Bindings

Los enlaces de datos conectan las propiedades de dos objetos, denominados origen y destino.Data bindings connect properties of two objects, called the source and the target. En el código, se requieren dos pasos: la BindingContext propiedad del objeto de destino debe establecerse en el objeto de origen y SetBinding se debe llamar al método (que se usa a menudo junto con la Binding clase) en el objeto de destino para enlazar una propiedad de ese objeto a una propiedad del objeto de origen.In code, two steps are required: The BindingContext property of the target object must be set to the source object, and the SetBinding method (often used in conjunction with the Binding class) must be called on the target object to bind a property of that object to a property of the source object.

La propiedad de destino debe ser una propiedad enlazable, lo que significa que el objeto de destino debe derivarse de BindableObject .The target property must be a bindable property, which means that the target object must derive from BindableObject. La documentación en línea Xamarin.Forms indica qué propiedades son propiedades que se pueden enlazar.The online Xamarin.Forms documentation indicates which properties are bindable properties. Una propiedad de como Label Text está asociada a la propiedad enlazable TextProperty .A property of Label such as Text is associated with the bindable property TextProperty.

En el marcado, también debe realizar los mismos dos pasos que se requieren en el código, con la excepción de que la Binding extensión de marcado toma el lugar de la SetBinding llamada y la Binding clase.In markup, you must also perform the same two steps that are required in code, except that the Binding markup extension takes the place of the SetBinding call and the Binding class.

Sin embargo, cuando se definen los enlaces de datos en XAML, hay varias maneras de establecer el BindingContext del objeto de destino.However, when you define data bindings in XAML, there are multiple ways to set the BindingContext of the target object. A veces se establece desde el archivo de código subyacente, a veces mediante StaticResource una x:Static extensión de marcado o, y a veces como el contenido de las BindingContext etiquetas de elemento de propiedad.Sometimes it’s set from the code-behind file, sometimes using a StaticResource or x:Static markup extension, and sometimes as the content of BindingContext property-element tags.

Los enlaces se usan con mayor frecuencia para conectar los objetos visuales de un programa con un modelo de datos subyacente, normalmente en una realización de la arquitectura de la aplicación MVVM (modelo-vista-ViewModel), como se describe en la parte 5. De los enlaces de datos a MVVM, pero también se pueden realizar otros escenarios.Bindings are used most often to connect the visuals of a program with an underlying data model, usually in a realization of the MVVM (Model-View-ViewModel) application architecture, as discussed in Part 5. From Data Bindings to MVVM, but other scenarios are possible.

Enlaces de vista a vistaView-to-View Bindings

Puede definir enlaces de datos para vincular las propiedades de dos vistas en la misma página.You can define data bindings to link properties of two views on the same page. En este caso, se establece el BindingContext del objeto de destino mediante la x:Reference extensión de marcado.In this case, you set the BindingContext of the target object using the x:Reference markup extension.

Este es un archivo XAML que contiene una Slider y dos Label vistas, una de las cuales se gira por el Slider valor y otra que muestra el Slider valor:Here’s a XAML file that contains a Slider and two Label views, one of which is rotated by the Slider value and another which displays the Slider value:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SliderBindingsPage"
             Title="Slider Bindings Page">

    <StackLayout>
        <Label Text="ROTATION"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}"
               FontAttributes="Bold"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="CenterAndExpand" />

        <Label BindingContext="{x:Reference slider}"
               Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"
               FontAttributes="Bold"
               FontSize="Large"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

SliderContiene un x:Name atributo al que hacen referencia las dos Label vistas mediante la extensión de x:Reference marcado.The Slider contains an x:Name attribute that is referenced by the two Label views using the x:Reference markup extension.

La x:Reference extensión de enlace define una propiedad denominada Name para establecer en el nombre del elemento al que se hace referencia, en este caso slider .The x:Reference binding extension defines a property named Name to set to the name of the referenced element, in this case slider. Sin embargo, la ReferenceExtension clase que define la x:Reference extensión de marcado también define un ContentProperty atributo para Name , lo que significa que no se requiere explícitamente.However, the ReferenceExtension class that defines the x:Reference markup extension also defines a ContentProperty attribute for Name, which means that it isn’t explicitly required. Solo para la variedad, el primero x:Reference incluye "Name =", pero el segundo no:Just for variety, the first x:Reference includes “Name=” but the second does not:

BindingContext="{x:Reference Name=slider}"
…
BindingContext="{x:Reference slider}"

La Binding extensión de marcado puede tener varias propiedades, al igual que BindingBase las Binding clases y.The Binding markup extension itself can have several properties, just like the BindingBase and Binding class. ContentPropertyPara Binding es Path , pero la parte "path =" de la extensión de marcado se puede omitir si la ruta de acceso es el primer elemento de la extensión de Binding marcado.The ContentProperty for Binding is Path, but the “Path=” part of the markup extension can be omitted if the path is the first item in the Binding markup extension. El primer ejemplo tiene "path =", pero el segundo ejemplo lo omite:The first example has “Path=” but the second example omits it:

Rotation="{Binding Path=Value}"
…
Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"

Todas las propiedades pueden estar en una línea o dividirse en varias líneas:The properties can all be on one line or separated into multiple lines:

Text="{Binding Value,
               StringFormat='The angle is {0:F0} degrees'}"

Haga lo que sea conveniente.Do whatever is convenient.

Observe la StringFormat propiedad en la segunda Binding extensión de marcado.Notice the StringFormat property in the second Binding markup extension. En Xamarin.Forms , los enlaces no realizan ninguna conversión de tipo implícita y, si necesita mostrar un objeto que no es una cadena como una cadena, debe proporcionar un convertidor de tipos o utilizar StringFormat .In Xamarin.Forms, bindings do not perform any implicit type conversions, and if you need to display a non-string object as a string you must provide a type converter or use StringFormat. En segundo plano, el String.Format método estático se usa para implementar StringFormat .Behind the scenes, the static String.Format method is used to implement StringFormat. Esto puede ser un problema, ya que las especificaciones de formato de .NET incluyen llaves, que también se utilizan para delimitar las extensiones de marcado.That’s potentially a problem, because .NET formatting specifications involve curly braces, which are also used to delimit markup extensions. Esto crea un riesgo de confusión en el analizador de XAML.This creates a risk of confusing the XAML parser. Para evitarlo, coloque toda la cadena de formato entre comillas simples:To avoid that, put the entire formatting string in single quotation marks:

Text="{Binding Value, StringFormat='The angle is {0:F0} degrees'}"

Este es el programa en ejecución:Here’s the running program:

Enlaces de vista a vistaView-to-View Bindings

Modo de enlaceThe Binding Mode

Una sola vista puede tener enlaces de datos en algunas de sus propiedades.A single view can have data bindings on several of its properties. Sin embargo, cada vista solo puede tener una BindingContext , por lo que varios enlaces de datos de esa vista deben tener todas las propiedades de referencia del mismo objeto.However, each view can have only one BindingContext, so multiple data bindings on that view must all reference properties of the same object.

La solución para este y otros problemas implica la Mode propiedad, que se establece en un miembro de la BindingMode enumeración:The solution to this and other problems involves the Mode property, which is set to a member of the BindingMode enumeration:

  • Default
  • OneWay: los valores se transfieren desde el origen al destino.OneWay — values are transferred from the source to the target
  • OneWayToSource: los valores se transfieren desde el destino al origen.OneWayToSource — values are transferred from the target to the source
  • TwoWay: los valores se transfieren en ambos sentidos entre el origen y el destino.TwoWay — values are transferred both ways between source and target
  • OneTime: los datos van desde el origen hasta el destino, pero solo cuando los BindingContext cambiosOneTime — data goes from source to target, but only when the BindingContext changes

En el programa siguiente se muestra un uso común de los OneWayToSource TwoWay modos de enlace y.The following program demonstrates one common use of the OneWayToSource and TwoWay binding modes. SliderHay cuatro vistas diseñadas para controlar las Scale Rotate propiedades,, RotateX y RotateY de Label .Four Slider views are intended to control the Scale, Rotate, RotateX, and RotateY properties of a Label. En primer lugar, parece como si estas cuatro propiedades de Label deben ser destinos de enlace de datos porque cada una se establece mediante Slider .At first, it seems as if these four properties of the Label should be data-binding targets because each is being set by a Slider. Sin embargo, el BindingContext de Label solo puede ser un objeto y hay cuatro controles deslizantes diferentes.However, the BindingContext of Label can be only one object, and there are four different sliders.

Por ese motivo, todos los enlaces se establecen de manera aparentemente inversa: el BindingContext de cada uno de los cuatro controles deslizantes se establece en Label , y los enlaces se establecen en las Value propiedades de los controles deslizantes.For that reason, all the bindings are set in seemingly backwards ways: The BindingContext of each of the four sliders is set to the Label, and the bindings are set on the Value properties of the sliders. Mediante el uso de los OneWayToSource TwoWay modos y, estas Value propiedades pueden establecer las propiedades de origen, que son las Scale Rotate propiedades,, RotateX y RotateY de Label :By using the OneWayToSource and TwoWay modes, these Value properties can set the source properties, which are the Scale, Rotate, RotateX, and RotateY properties of the Label:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="XamlSamples.SliderTransformsPage"
             Padding="5"
             Title="Slider Transforms Page">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <!-- Scaled and rotated Label -->
        <Label x:Name="label"
               Text="TEXT"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

        <!-- Slider and identifying Label for Scale -->
        <Slider x:Name="scaleSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="1" Grid.Column="0"
                Maximum="10"
                Value="{Binding Scale, Mode=TwoWay}" />

        <Label BindingContext="{x:Reference scaleSlider}"
               Text="{Binding Value, StringFormat='Scale = {0:F1}'}"
               Grid.Row="1" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for Rotation -->
        <Slider x:Name="rotationSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="2" Grid.Column="0"
                Maximum="360"
                Value="{Binding Rotation, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationSlider}"
               Text="{Binding Value, StringFormat='Rotation = {0:F0}'}"
               Grid.Row="2" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for RotationX -->
        <Slider x:Name="rotationXSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="3" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationX, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationXSlider}"
               Text="{Binding Value, StringFormat='RotationX = {0:F0}'}"
               Grid.Row="3" Grid.Column="1"
               VerticalTextAlignment="Center" />

        <!-- Slider and identifying Label for RotationY -->
        <Slider x:Name="rotationYSlider"
                BindingContext="{x:Reference label}"
                Grid.Row="4" Grid.Column="0"
                Maximum="360"
                Value="{Binding RotationY, Mode=OneWayToSource}" />

        <Label BindingContext="{x:Reference rotationYSlider}"
               Text="{Binding Value, StringFormat='RotationY = {0:F0}'}"
               Grid.Row="4" Grid.Column="1"
               VerticalTextAlignment="Center" />
    </Grid>
</ContentPage>

Los enlaces de tres de las Slider vistas son OneWayToSource , lo que significa que el Slider valor produce un cambio en la propiedad de BindingContext , que es el Label denominado label .The bindings on three of the Slider views are OneWayToSource, meaning that the Slider value causes a change in the property of its BindingContext, which is the Label named label. Estas tres Slider vistas producen cambios en las Rotate RotateX propiedades, y RotateY de Label .These three Slider views cause changes to the Rotate, RotateX, and RotateY properties of the Label.

Sin embargo, el enlace para la Scale propiedad es TwoWay .However, the binding for the Scale property is TwoWay. Esto se debe a que la Scale propiedad tiene un valor predeterminado de 1 y el uso de un TwoWay enlace hace que el Slider valor inicial se establezca en 1 en lugar de 0.This is because the Scale property has a default value of 1, and using a TwoWay binding causes the Slider initial value to be set at 1 rather than 0. Si ese enlace era OneWayToSource , la Scale propiedad se establecería inicialmente en 0 desde el Slider valor predeterminado.If that binding were OneWayToSource, the Scale property would initially be set to 0 from the Slider default value. LabelNo sería visible y eso podría causar confusión al usuario.The Label would not be visible, and that might cause some confusion to the user.

Enlaces hacia atrásBackwards Bindings

Nota

La VisualElement clase también tiene ScaleX ScaleY las propiedades y, que escalan VisualElement en el eje x e y, respectivamente.The VisualElement class also has ScaleX and ScaleY properties, which scale the VisualElement on the x-axis and y-axis respectively.

Enlaces y coleccionesBindings and Collections

Nada ilustra la eficacia de los enlaces de datos y XAML mejor que una plantilla ListView .Nothing illustrates the power of XAML and data bindings better than a templated ListView.

ListViewdefine una ItemsSource propiedad de tipo IEnumerable y muestra los elementos de esa colección.ListView defines an ItemsSource property of type IEnumerable, and it displays the items in that collection. Estos elementos pueden ser objetos de cualquier tipo.These items can be objects of any type. De forma predeterminada, ListView usa el ToString método de cada elemento para mostrar ese elemento.By default, ListView uses the ToString method of each item to display that item. A veces, esto es exactamente lo que desea, pero en muchos casos, ToString solo devuelve el nombre de clase completo del objeto.Sometimes this is just what you want, but in many cases, ToString returns only the fully-qualified class name of the object.

Sin embargo, los elementos de la ListView colección se pueden mostrar de la forma que desee mediante el uso de una plantilla, que implica una clase que deriva de Cell .However, the items in the ListView collection can be displayed any way you want through the use of a template, which involves a class that derives from Cell. La plantilla se clona para cada elemento de ListView , y los enlaces de datos que se han establecido en la plantilla se transfieren a los clones individuales.The template is cloned for every item in the ListView, and data bindings that have been set on the template are transferred to the individual clones.

Con mucha frecuencia, querrá crear una celda personalizada para estos elementos mediante la ViewCell clase.Very often, you’ll want to create a custom cell for these items using the ViewCell class. Este proceso es un poco confuso en el código, pero en XAML resulta muy sencillo.This process is somewhat messy in code, but in XAML it becomes very straightforward.

En el proyecto XamlSamples se incluye una clase denominada NamedColor .Included in the XamlSamples project is a class called NamedColor. Cada NamedColor objeto tiene Name FriendlyName propiedades y de tipo string , y una Color propiedad de tipo Color .Each NamedColor object has Name and FriendlyName properties of type string, and a Color property of type Color. Además, NamedColor tiene 141 campos estáticos de solo lectura de tipo Color correspondientes a los colores definidos en la Xamarin.Forms Color clase.In addition, NamedColor has 141 static read-only fields of type Color corresponding to the colors defined in the Xamarin.Forms Color class. Un constructor estático crea una IEnumerable<NamedColor> colección que contiene NamedColor objetos correspondientes a estos campos estáticos y lo asigna a su propiedad estática pública All .A static constructor creates an IEnumerable<NamedColor> collection that contains NamedColor objects corresponding to these static fields, and assigns it to its public static All property.

Establecer la NamedColor.All propiedad estática en ItemsSource de un ListView es fácil con la extensión de x:Static marcado:Setting the static NamedColor.All property to the ItemsSource of a ListView is easy using the x:Static markup extension:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples;assembly=XamlSamples"
             x:Class="XamlSamples.ListViewDemoPage"
             Title="ListView Demo Page">

    <ListView ItemsSource="{x:Static local:NamedColor.All}" />

</ContentPage>

La presentación resultante establece que los elementos son realmente de tipo XamlSamples.NamedColor :The resultant display establishes that the items are truly of type XamlSamples.NamedColor:

Enlazar a una colecciónBinding to a Collection

No es mucha información, pero ListView es desplazable y seleccionable.It’s not much information, but the ListView is scrollable and selectable.

Para definir una plantilla para los elementos, querrá dividir la ItemTemplate propiedad como un elemento de propiedad y establecerla en un DataTemplate , que luego hace referencia a un ViewCell .To define a template for the items, you’ll want to break out the ItemTemplate property as a property element, and set it to a DataTemplate, which then references a ViewCell. En la View propiedad de puede ViewCell definir un diseño de una o varias vistas para mostrar cada elemento.To the View property of the ViewCell you can define a layout of one or more views to display each item. Este es un ejemplo sencillo:Here’s a simple example:

<ListView ItemsSource="{x:Static local:NamedColor.All}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <ViewCell.View>
                    <Label Text="{Binding FriendlyName}" />
                </ViewCell.View>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Nota

El origen de enlace para las celdas y los elementos secundarios de las celdas es la ListView.ItemsSource colección.The binding source for cells, and children of cells, is the ListView.ItemsSource collection.

El Label elemento se establece en la View propiedad de ViewCell .The Label element is set to the View property of the ViewCell. (Las ViewCell.View etiquetas no son necesarias porque la View propiedad es el contenido de ViewCell .) Este marcado muestra la FriendlyName propiedad de cada NamedColor objeto:(The ViewCell.View tags are not needed because the View property is the content property of ViewCell.) This markup displays the FriendlyName property of each NamedColor object:

Enlazar a una colección con un DataTemplateBinding to a Collection with a DataTemplate

Mucho mejor.Much better. Ahora todo lo que se necesita es spruce de la plantilla de elemento con más información y el color real.Now all that’s needed is to spruce up the item template with more information and the actual color. Para admitir esta plantilla, algunos valores y objetos se han definido en el Diccionario de recursos de la página:To support this template, some values and objects have been defined in the page’s resource dictionary:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:XamlSamples"
             x:Class="XamlSamples.ListViewDemoPage"
             Title="ListView Demo Page">

    <ContentPage.Resources>
        <ResourceDictionary>
            <OnPlatform x:Key="boxSize"
                        x:TypeArguments="x:Double">
                <On Platform="iOS, Android, UWP" Value="50" />
            </OnPlatform>

            <OnPlatform x:Key="rowHeight"
                        x:TypeArguments="x:Int32">
                <On Platform="iOS, Android, UWP" Value="60" />
            </OnPlatform>

            <local:DoubleToIntConverter x:Key="intConverter" />

        </ResourceDictionary>
    </ContentPage.Resources>

    <ListView ItemsSource="{x:Static local:NamedColor.All}"
              RowHeight="{StaticResource rowHeight}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="5, 5, 0, 5"
                                 Orientation="Horizontal"
                                 Spacing="15">

                        <BoxView WidthRequest="{StaticResource boxSize}"
                                 HeightRequest="{StaticResource boxSize}"
                                 Color="{Binding Color}" />

                        <StackLayout Padding="5, 0, 0, 0"
                                     VerticalOptions="Center">

                            <Label Text="{Binding FriendlyName}"
                                   FontAttributes="Bold"
                                   FontSize="Medium" />

                            <StackLayout Orientation="Horizontal"
                                         Spacing="0">
                                <Label Text="{Binding Color.R,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat='R={0:X2}'}" />

                                <Label Text="{Binding Color.G,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat=', G={0:X2}'}" />

                                <Label Text="{Binding Color.B,
                                       Converter={StaticResource intConverter},
                                       ConverterParameter=255,
                                       StringFormat=', B={0:X2}'}" />
                            </StackLayout>
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

Observe el uso de OnPlatform para definir el tamaño de un BoxView y el alto de las ListView filas.Notice the use of OnPlatform to define the size of a BoxView and the height of the ListView rows. Aunque los valores de todas las plataformas son los mismos, el marcado se puede adaptar fácilmente a otros valores para ajustar la pantalla.Although the values for all the platforms are the same, the markup could easily be adapted for other values to fine-tune the display.

Enlace de convertidores de valoresBinding Value Converters

En el archivo XAML de demostración de ListView anterior se muestran las R propiedades individuales, G y B de la Xamarin.Forms Color estructura.The previous ListView Demo XAML file displays the individual R, G, and B properties of the Xamarin.Forms Color structure. Estas propiedades son del tipo double y van de 0 a 1.These properties are of type double and range from 0 to 1. Si desea mostrar los valores hexadecimales, no se puede usar StringFormat con una especificación de formato "x2".If you want to display the hexadecimal values, you can’t simply use StringFormat with an “X2” formatting specification. Eso solo sirve para enteros y, además, los double valores se deben multiplicar por 255.That only works for integers and besides, the double values need to be multiplied by 255.

Este pequeño problema se resolvió con un convertidor de valores, también denominado convertidor de enlace.This little problem was solved with a value converter, also called a binding converter. Se trata de una clase que implementa la IValueConverter interfaz, lo que significa que tiene dos métodos denominados Convert y ConvertBack .This is a class that implements the IValueConverter interface, which means it has two methods named Convert and ConvertBack. ConvertSe llama al método cuando se transfiere un valor desde el origen al destino; ConvertBack se llama al método para las transferencias del destino al origen en los OneWayToSource TwoWay enlaces o:The Convert method is called when a value is transferred from source to target; the ConvertBack method is called for transfers from target to source in OneWayToSource or TwoWay bindings:

using System;
using System.Globalization;
using Xamarin.Forms;

namespace XamlSamples
{
    class DoubleToIntConverter : IValueConverter
    {
        public object Convert(object value, Type targetType,
                              object parameter, CultureInfo culture)
        {
            double multiplier;

            if (!Double.TryParse(parameter as string, out multiplier))
                multiplier = 1;

            return (int)Math.Round(multiplier * (double)value);
        }

        public object ConvertBack(object value, Type targetType,
                                  object parameter, CultureInfo culture)
        {
            double divider;

            if (!Double.TryParse(parameter as string, out divider))
                divider = 1;

            return ((double)(int)value) / divider;
        }
    }
}

El ConvertBack método no desempeña un rol en este programa porque los enlaces son solo una forma de origen a destino.The ConvertBack method does not play a role in this program because the bindings are only one way from source to target.

Un enlace hace referencia a un convertidor de enlace con la Converter propiedad.A binding references a binding converter with the Converter property. Un convertidor de enlaces también puede aceptar un parámetro especificado con la ConverterParameter propiedad.A binding converter can also accept a parameter specified with the ConverterParameter property. Para algunas versatilidad, este es el modo en que se especifica el multiplicador.For some versatility, this is how the multiplier is specified. El convertidor de enlace comprueba si el parámetro de convertidor tiene un double valor válido.The binding converter checks the converter parameter for a valid double value.

Se crea una instancia del convertidor en el Diccionario de recursos para que se pueda compartir entre varios enlaces:The converter is instantiated in the resource dictionary so it can be shared among multiple bindings:

<local:DoubleToIntConverter x:Key="intConverter" />

Tres enlaces de datos hacen referencia a esta instancia única.Three data bindings reference this single instance. Tenga en cuenta que la Binding extensión de marcado contiene una extensión de marcado incrustada StaticResource :Notice that the Binding markup extension contains an embedded StaticResource markup extension:

<Label Text="{Binding Color.R,
                      Converter={StaticResource intConverter},
                      ConverterParameter=255,
                      StringFormat='R={0:X2}'}" />

Este es el resultado:Here’s the result:

Enlazar a una colección con un DataTemplate y convertidoresBinding to a Collection with a DataTemplate and Converters

ListViewEs bastante sofisticado para controlar los cambios que podrían producirse dinámicamente en los datos subyacentes, pero solo si se realizan determinados pasos.The ListView is quite sophisticated in handling changes that might dynamically occur in the underlying data, but only if you take certain steps. Si la colección de elementos asignada a la ItemsSource propiedad de ListView cambia durante el tiempo de ejecución, es decir, si se pueden agregar o quitar elementos de la colección, utilice una ObservableCollection clase para estos elementos.If the collection of items assigned to the ItemsSource property of the ListView changes during runtime—that is, if items can be added to or removed from the collection—use an ObservableCollection class for these items. ObservableCollectionimplementa la INotifyCollectionChanged interfaz e ListView instalará un controlador para el CollectionChanged evento.ObservableCollection implements the INotifyCollectionChanged interface, and ListView will install a handler for the CollectionChanged event.

Si las propiedades de los elementos cambian durante el tiempo de ejecución, los elementos de la colección deben implementar la INotifyPropertyChanged interfaz y los cambios de señal en los valores de propiedad mediante el PropertyChanged evento.If properties of the items themselves change during runtime, then the items in the collection should implement the INotifyPropertyChanged interface and signal changes to property values using the PropertyChanged event. Esto se muestra en la siguiente parte de esta serie, parte 5. Del enlace de datos a MVVM.This is demonstrated in the next part of this series, Part 5. From Data Binding to MVVM.

ResumenSummary

Los enlaces de datos proporcionan un mecanismo eficaz para vincular propiedades entre dos objetos dentro de una página o entre objetos visuales y datos subyacentes.Data bindings provide a powerful mechanism for linking properties between two objects within a page, or between visual objects and underlying data. Pero cuando la aplicación comienza a trabajar con orígenes de datos, un patrón de arquitectura de aplicación popular comienza a surgir como un paradigma útil.But when the application begins working with data sources, a popular application architectural pattern begins to emerge as a useful paradigm. Esto se trata en la parte 5. De enlaces de datos a MVVM.This is covered in Part 5. From Data Bindings to MVVM.