Introducción al enlace de datos (XAML)

Applies to Windows and Windows Phone

El enlace de datos ofrece a las aplicaciones de Windows en tiempo de ejecución con C++, C# o Visual Basic una manera simple de mostrar datos e interactuar con ellos. La manera en la que se muestran los datos es independiente de la administración de los datos. Una conexión, o enlace, entre la interfaz de usuario y el objeto de datos permite que los datos fluyan entre ellos. Cuando se establece un enlace y los datos cambian, los elementos de la interfaz de usuario enlazados a los datos pueden mostrar los cambios automáticamente. De manera similar, los cambios que realiza el usuario en un elemento de la interfaz de usuario se pueden guardar en el objeto de datos. Por ejemplo, si el usuario edita el valor de un TextBox, el valor de los datos subyacentes se actualiza automáticamente para reflejar ese cambio.

Algunos escenarios de enlace comunes incluyen el enlace de un ListBox a una lista de encabezados o una Image en la foto del usuario actual.

En este tema se describen detalladamente las características del enlace de datos. Para obtener una introducción rápida a los conceptos, consulta Inicio rápido: enlazar datos a controles.

Muestras de código: En este tema se usan ejemplos de código y extractos de muestras simples para ilustrar conceptos básicos del enlace de datos. Si quieres ver muestras completas, consulta:

Para ver un ejemplo completo en el que se usa ampliamente el enlace de datos, consulta la aplicación de ejemplo Reversi. Para obtener más información, consulta el tema sobre Reversi: un juego de la Tienda Windows en XAML, C# y C++ y la sección acerca del enlace de datos del tema que explica cómo la muestra de Reversi usa las características de aplicación de la Tienda Windows.

Para obtener otros ejemplos de C++, consulta el tema sobre cómo crear una aplicación con C++.

Guía básica: Relación de este tema con los demás. Consulta:

Conexión de elementos de la interfaz de usuario con datos

Todos los enlaces incluyen lo siguiente:

  • Un origen de enlace, que es un objeto con los datos que quieres representar.
  • Un destino de enlace, que es una DependencyProperty de FrameworkElement para representar los datos.
  • Un objeto Binding, que mueve los datos entre el origen y el destino y que puede cambiar su formato a través de un convertidor de valores opcional.

El origen puede ser:

  • Cualquier objeto de Common Language Runtime (CLR), incluso el elemento de destino en sí u otros elementos de la interfaz de usuario. Si el destino está en una plantilla de datos, el origen puede ser el elemento de la interfaz de usuario al cual se aplica la plantilla. Las clases que defines en C# y Visual Basic producen objetos de CLR, de manera que son enlazables de manera predeterminada.
  • Cualquier objeto de Windows en tiempo de ejecución de un tipo que tenga un BindableAttribute o implemente ICustomPropertyProvider. Las clases que defines en C++ producen objetos de Windows en tiempo de ejecución, de manera que requieren que uno de estos enfoques sea enlazable.

El destino puede ser cualquier DependencyProperty de un FrameworkElement.

El motor de enlace obtiene información del objeto Binding acerca de lo siguiente:

  • Los objetos de origen y de destino.
  • La dirección del flujo de datos. La dirección se especifica al configurar la propiedad Binding.Mode.
  • El convertidor de valores, si es que hay uno presente. Un convertidor de valores se especifica al establecer la propiedad Converter en una instancia de una clase que implemente IValueConverter.
  • Otra configuración, como FallbackValue y TargetNullValue. Consulta la clase Binding para obtener la lista completa de propiedades.

Por ejemplo, la propiedad Foreground de un TextBox puede enlazarse a un SolidColorBrush para que el color del texto pueda cambiar en función de los datos. En este escenario, la propiedad Foreground es el destino y el objeto SolidColorBrush es el origen del enlace.

En el siguiente ejemplo se muestra cómo enlazar el color Foreground de un TextBox con un SolidColorBrush. El origen del enlace es una propiedad de la clase MyColors, que se describe más adelante en este tema.



<TextBox x:Name="MyTextBox" Text="Text" Foreground="{Binding Brush1}"/>




// Create an instance of the MyColors class 
// that implements INotifyPropertyChanged.
MyColors textcolor = new MyColors();

// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);

// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;


Nota  En este ejemplo se usa la sintaxis de atributo XAML para crear el enlace. También puedes usar la sintaxis de un elemento de objeto para crear el enlace en XAML. Para obtener más información, consulta Introducción a XAML.

El enlace se crea en XAML con la sintaxis {Binding ...}. El origen se establece en el código al configurar la propiedad DataContext del TextBox.

Se hereda el contexto de datos. Si estableces el contexto de datos en un elemento primario, todos sus elementos secundarios usarán el mismo contexto de datos. Un elemento secundario puede invalidar este comportamiento, al configurar la propiedad Source en su objeto de enlace o al configurar su DataContext. Esta invalidación después se aplicará a todos los elementos secundarios.

La configuración del contexto de datos es útil cuando quieres tener varios enlaces que usen el mismo origen. Para configurar el origen de un solo enlace, establece la propiedad Source en el objeto Binding.

También puedes usar la propiedad ElementName o la propiedad RelativeSource para especificar el origen de enlace. La propiedad ElementName es útil cuando estás enlazando elementos en la aplicación, por ejemplo, cuando estás usando un control deslizante para ajustar el ancho de un botón. La propiedad RelativeSource es útil cuando el enlace se especifica en una ControlTemplate. Para obtener más información, consulta el tema sobre extensión de marcado de enlace y extensión de marcado de RelativeSource.

Para enlazar a una propiedad del objeto de origen, establece la propiedad Binding.Path. La propiedad Path admite una variedad de opciones de sintaxis para enlazar a propiedades anidadas, propiedades adjuntas e indizadores de cadenas y de enteros. Para obtener más información, consulta Sintaxis de property-path. El enlace a indizadores de cadenas te ofrece el mismo efecto que el enlace a propiedades dinámicas sin tener que implementar ICustomPropertyProvider.

Si enlazas un control de texto con un valor que no es una cadena, el motor de enlace de datos lo convertirá en una. Si el valor es un tipo de referencia, dicho motor recuperará el valor de cadena llamando a ICustomPropertyProvider.GetStringRepresentation o a IStringable.ToString, si están disponibles, o bien llamando a Object.ToString, si no lo están. Pero ten en cuenta que el motor de enlace de datos pasará por alto las implementaciones de ToString que oculten la implementación de la clase base. Las implementaciones de la subclase deben invalidar, en cambio, el método ToString de la clase base. De forma similar, en los lenguajes no administrados, todos los objetos administrados parecen implementar ICustomPropertyProvider e IStringable. Pero todas las llamadas a GetStringRepresentation y a IStringable.ToString se enrutan a Object.ToString o a una invalidación de ese método y nunca a una implementación de ToString que oculta la implementación de la clase base.

En conjunto, el ejemplo anterior hace que el motor de enlace cree un enlace que, de manera predeterminada, es un enlace unidireccional. Conecta la propiedad Foreground del TextBox con la propiedad Brush1 del objeto textcolor.

Crear enlaces en el código

También puedes conectar elementos de la interfaz de usuario a datos usando código de procedimientos en lugar de XAML. Para ello, crea un nuevo objeto Binding, establece las propiedades correspondientes y luego llama a FrameworkElement.SetBinding o a BindingOperations.SetBinding. Crear enlaces mediante programación te resultará útil si quieres elegir los valores de propiedad de los enlaces en tiempo de ejecución o compartir un único enlace entre varios controles. Pero ten en cuenta que no puedes cambiar los valores de propiedad de los enlaces después de llamar a SetBinding.

En el siguiente ejemplo se muestra cómo implementar el enlace anterior en el código.



<TextBox x:Name="MyTextBox" Text="Text"/>




// Create an instance of the MyColors class 
// that implements INotifyPropertyChanged.
MyColors textcolor = new MyColors();

// Brush1 is set to be a SolidColorBrush with the value Red.
textcolor.Brush1 = new SolidColorBrush(Colors.Red);

// Set the DataContext of the TextBox MyTextBox.
MyTextBox.DataContext = textcolor;

// Create the binding and associate it with the text box.
Binding binding = new Binding() { Path = new PropertyPath("Brush1") };
MyTextBox.SetBinding(TextBox.ForegroundProperty, binding);


Dirección del flujo de datos

Cada enlace tiene una propiedad Mode, que determina cómo y cuándo fluyen los datos. Las aplicaciones de Windows en tiempo de ejecución con C++, C# o Visual Basic pueden usar tres tipos de enlaces:

  • Los enlaces OneTime actualizan el destino con los datos del origen cuando se crea el enlace.
  • Los enlaces OneWay actualizan el destino con los datos de origen cuando se crea el enlace y cada vez que cambian los datos. Este es el modo predeterminado.
  • Los enlaces TwoWay actualizan tanto el destino como el origen cuando alguno de ellos cambia. Una excepción de este comportamiento es que los cambios de TextBox.Text no se envían a un origen enlazado después de cada pulsación de tecla por parte del usuario a menos que Binding.UpdateSourceTrigger esté configurado en PropertyChanged. Por defecto, los cambios se envían solo cuando TextBox pierde el foco.

Puedes cambiar el comportamiento de los enlaces TwoWay de modo que los valores no se copien al origen de forma automática, sino solo cuando decidas hacerlo. Para hacerlo, establece la propiedad Binding.UpdateSourceTrigger en Explicit. Luego llama a GetBindingExpression en el destino para obtener un objeto BindingExpression y después llama a BindingExpression.UpdateSource para actualizar el origen de datos mediante programación.

Notificación de cambios

Para que los cambios en el objeto de origen se propaguen al destino, el origen debe implementar la interfaz INotifyPropertyChanged. INotifyPropertyChanged controla el evento PropertyChanged. Este evento indica al motor de enlace que el origen ha cambiado, para que actualice el valor de destino. En C# o Microsoft Visual Basic, implementas System.ComponentModel.INotifyPropertyChanged. En extensiones de componentes de Visual C++ (C++/CX), implementas Windows::UI::Xaml::Data::INotifyPropertyChanged.

En este ejemplo, la clase MyColors implementa la interfaz INotifyPropertyChanged para el enlace OneWay.



// Create a class that implements INotifyPropertyChanged.
public class MyColors : INotifyPropertyChanged
{
    private SolidColorBrush _Brush1;

    // Declare the PropertyChanged event.
    public event PropertyChangedEventHandler PropertyChanged;

    // Create the property that will be the source of the binding.
    public SolidColorBrush Brush1
    {
        get { return _Brush1; }
        set
        {
            _Brush1 = value;
            // Call NotifyPropertyChanged when the source property 
            // is updated.
            NotifyPropertyChanged("Brush1");
        }
    }

    // NotifyPropertyChanged will fire the PropertyChanged event, 
    // passing the source property that is being updated.
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, 
                new PropertyChangedEventArgs(propertyName));
        }
    }
}


Puedes activar el evento PropertyChanged para indicar que todas las propiedades no indizadoras del objeto han cambiado utilizando un valor PropertyChangedEventArgs.PropertyName de String.Empty. Ten en cuenta que no puedes usar null (Nothing en Visual Basic) para esto, como lo haces en Windows Presentation Foundation (WPF) y Microsoft Silverlight.

Nota  En C# o Microsoft Visual Basic, usas System.ComponentModel.PropertyChangedEventArgs. En C++/CX, usas Windows::UI::Xaml::Data::PropertyChangedEventArgs.

También puedes usar la notificación de cambios con propiedades de indizador. Puedes activar el evento PropertyChanged para indicar que las propiedades de indizador del objeto han cambiado mediante un valor PropertyChangedEventArgs.PropertyName de "Item[indexer]" para indizadores específicos (donde indexer es el valor de índice) o "Item[]" para todos los indizadores.

Enlace a colecciones

Un objeto de origen de enlace puede tratarse como un solo objeto cuyas propiedades contienen datos, o bien, como una colección de objetos. Por ejemplo, puede que quieras mostrar una lista de elementos, como facturas mensuales de tarjetas de crédito. Para hacerlo, usa un ItemsControl y una DataTemplate para mostrar cada elemento en una colección.



<Grid.Resources>

  <DataTemplate x:Name="dataTemplate">
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <TextBlock Grid.Column="0" 
        Text="{Binding Month, Converter={StaticResource Converter1}}"/>
      <TextBlock Grid.Column="1" Text="{Binding Total}"/>    
    </Grid>
  </DataTemplate>

</Grid.Resources>

<ItemsControl x:Name="IC1" ItemsSource="{Binding}" 
  ItemTemplate="{StaticResource dataTemplate}"/>


En código de C# y Visual Basic, puedes rellenar y enlazar a una List(Of T) para mostrar una colección fija. Si se agregan o quitan elementos de la colección en el tiempo de ejecución, y quieres que el destino actualice el ItemsSource cuando eso ocurra, usa ObservableCollection(Of T) en su lugar. En código de C++, puedes rellenar y enlazar a instancias de Vector<T> para colecciones fijas y no fijas. Para enlazar tus propias clases de colecciones, usa las directrices de la siguiente tabla.

El sistema de enlace de datos admite los siguientes escenarios de enlace.

EscenarioC# y VB (CLR)C++
Enlazar a un objeto.Puede ser cualquier objeto.El objeto debe tener BindableAttribute o implementar ICustomPropertyProvider.
Obtener actualizaciones de cambios de propiedades de un objeto enlazado.El objeto debe implementar System.ComponentModel.INotifyPropertyChanged.El objeto debe implementar Windows.UI.Xaml.Data.INotifyPropertyChanged.
Enlazar a una colección. List(Of T) Platform::Collections::Vector<T>
Obtener actualizaciones de cambios de colecciones de una colección enlazada. ObservableCollection(Of T) Platform::Collections::Vector<T>
Implementar una colección compatible con enlaces.Extender List(Of T) o implementar IList, IList(de Object), IEnumerable, o IEnumerable(de Object). No se admite el enlace a IList(Of T) y IEnumerable(Of T) genéricos.Implementar IBindableVector, IBindableIterable, IVector<Object^>, IIterable<Object^>, IVector<IInspectable*> o IIterable<IInspectable*>. No se admite el enlace a IVector<T> y IIterable<T> genéricos.
Implementar una colección que admita actualizaciones de cambios de colecciones.Extender ObservableCollection(Of T) o implementar IList y INotifyCollectionChanged (no genéricos).Implementar IBindableVector y IBindableObservableVector.
Implementar una colección compatible con la carga incremental.Extender ObservableCollection(Of T) o implementar IList y INotifyCollectionChanged (no genéricos). De forma adicional, implementar ISupportIncrementalLoading. Implementar IBindableVector, IBindableObservableVector y ISupportIncrementalLoading.

 

Carga de datos de forma incremental

Con la carga incremental, puedes enlazar controles de lista a orígenes de datos que son arbitrariamente de gran tamaño y aun así lograr un alto rendimiento. Por ejemplo, puedes enlazar controles de lista a resultados de consulta de imágenes de Bing sin tener que cargarlos a todos de una vez. Solo cargas algunos resultados inmediatamente y después cargas otros, según sea necesario. Para admitir la carga incremental, debes implementar ISupportIncrementalLoading en un origen de datos compatible con la notificación de cambios de colección. Cuando el motor de enlace de datos solicite más datos, tu origen de datos debe realizar las solicitudes apropiadas, integrar los resultados y después enviar las debidas notificaciones para actualizar la interfaz de usuario. Para obtener información, consulta la muestra de enlace de datos XAML.

Enlace a listas de archivos y carpetas

  • Applies to Windows

Para recuperar datos de archivos y carpetas, puedes usar las API en el espacio de nombres Windows.Storage. No obstante, los distintos métodos GetFilesAsync, GetFoldersAsync y GetItemsAsync no devuelven valores adecuados para enlaces a controles de lista. En cambio, debes enlazar a los valores devueltos de los métodos GetVirtualizedFilesVector, GetVirtualizedFoldersVector y GetVirtualizedItemsVector de la clase FileInformationFactory. En el siguiente ejemplo de código de la muestra de StorageDataSource y GetVirtualizedFilesVector encontrarás el patrón de uso más común.


protected override void OnNavigatedTo(NavigationEventArgs e)
{
    var library = Windows.Storage.KnownFolders.PicturesLibrary;
    var queryOptions = new Windows.Storage.Search.QueryOptions();
    queryOptions.FolderDepth = Windows.Storage.Search.FolderDepth.Deep;
    queryOptions.IndexerOption = Windows.Storage.Search.IndexerOption.UseIndexerWhenAvailable;

    var fileQuery = library.CreateFileQueryWithOptions(queryOptions);

    var fif = new Windows.Storage.BulkAccess.FileInformationFactory(
        fileQuery,
        Windows.Storage.FileProperties.ThumbnailMode.PicturesView,
        190,
        Windows.Storage.FileProperties.ThumbnailOptions.UseCurrentScale,
        false
        );

    var dataSource = fif.GetVirtualizedFilesVector();
    PicturesGrid.ItemsSource = dataSource;
}


  • Applies to Windows

Normalmente usarás este enfoque para crear una vista de solo lectura de la información de archivo y carpeta. Puedes crear enlaces bidireccionales a las propiedades de archivo y carpeta; por ejemplo, para permitir que los usuarios califiquen una canción en una vista de música. No obstante, ningún cambio persiste hasta que no llames al método SavePropertiesAsync apropiado (por ejemplo, MusicProperties.SavePropertiesAsync). Debes confirmar cambios cuando el elemento pierde el foco, porque esto desencadena el restablecimiento de la selección.

Ten en cuenta que el enlace bidireccional con esta técnica solo funciona con ubicaciones indizadas, como Música. Puedes determinar si una ubicación es indizada llamando al método FolderInformation.GetIndexedStateAsync.

Ten en cuenta también que un vector virtualizado puede devolver null para algunos elementos antes de que rellene su valor. Por ejemplo, debes comprobar null antes de usar el valor SelectedItem de un control de lista enlazado a un vector virtualizado, o en su lugar, utilizar SelectedIndex.

Agrupación de datos y seguimiento del elemento actual

También puedes enlazar a instancias de la clase CollectionViewSource para mostrar colecciones de colecciones y para realizar un seguimiento del elemento actual en vistas múltiples. Generalmente defines un CollectionViewSource como un recurso XAML y enlazas a él con la extensión de marcado StaticResource. Por lo tanto, puedes establecer la propiedad Source en código subyacente para un tipo de colección admitido.

Cualquier control que enlaces al mismo CollectionViewSource siempre tendrá el mismo elemento actual, y cualquier enlace con la configuración Path enlazará automáticamente a las propiedades del elemento actual. Puedes acceder al elemento actual mediante programación a través de la propiedad ICollectionView.CurrentItem del valor de la propiedad CollectionViewSource.View.

Si los elementos de la colección son colecciones en sí, o son objetos que contienen colecciones, puedes mostrar las colecciones como grupos dentro de una colección más grande. Para hacerlo, establece la propiedad IsSourceGrouped en true. Si los elementos contienen colecciones pero no son colecciones en sí, también debes establecer la propiedad ItemsPath en el nombre de la propiedad de colección. Por ejemplo, si enlazas a una colección CustomerList de objetos Customer y la clase Customer tiene una propiedad Orders, que es una colección de objetos Order, puedes agrupar pedidos por cliente con el siguiente XAML.


<local:CustomerList x:Key="CustomerData"/>
<CollectionViewSource x:Name="Customers"
  Source="{StaticResource CustomerData}"
  IsSourceGrouped="True" ItemsPath="Orders"/>


Después puedes crear una plantilla de encabezado de grupo que enlace a propiedades de la clase Customer, así como una plantilla de elemento que enlace a propiedades de la clase Order. También puedes acceder a los grupos mediante programación, a través de la propiedad CollectionViewSource.CollectionGroups.

En el siguiente ejemplo de código se demuestra cómo enlazar un control de ListBox a los resultados de una consulta LINQ de agrupación. En este ejemplo, una colección de equipos se agrupa por ciudad y se muestra con el nombre de ciudad en los encabezados de grupo. Esto se indica en la ruta de acceso de la propiedad "Key" en referencia al valor Key de grupo. Para obtener la lista completa de códigos, consulta la muestra de enlace de datos. Para obtener ejemplos similares de código que muestran agrupamientos, consulta la muestra de GridView agrupada.


<Grid>

  <Grid.Resources>
    <CollectionViewSource x:Name="groupInfoCVS" IsSourceGrouped="true"/>
  </Grid.Resources>

  <ListBox x:Name="lbGroupInfoCVS" 
    ItemsSource="{Binding Source={StaticResource groupInfoCVS}}">

    <ListBox.GroupStyle>
      <GroupStyle>
        <GroupStyle.HeaderTemplate>
          <DataTemplate>

            <TextBlock Text="{Binding Key}" />

          </DataTemplate>
        </GroupStyle.HeaderTemplate>
      </GroupStyle>
    </ListBox.GroupStyle>

    <ListBox.ItemTemplate>
      <DataTemplate>

        <Border Background="{Binding Color}" 
          Width="200" CornerRadius="10" HorizontalAlignment="Left">

          <TextBlock Text="{Binding Name}" 
            Style="{StaticResource DescriptionTextStyle}" 
            HorizontalAlignment="Center" FontWeight="Bold"/>

        </Border>
      </DataTemplate>
    </ListBox.ItemTemplate>

  </ListBox>

</Grid>



Teams teams = new Teams();
var result = 
    from t in teams 
    group t by t.City into g 
    orderby g.Key 
    select g;
groupInfoCVS.Source = result;


Otra opción posible cuando enlazas a datos de varios niveles, como categorías con subcategorías, es mostrar los niveles como una serie de listas. De esta manera, la selección en una sola lista afecta el contenido de las listas subsiguientes. Puedes mantener las listas sincronizadas, al enlazar cada una de ellas a su propio CollectionViewSource y al enlazar las instancias de CollectionViewSource juntas en una cadena. Para obtener más información, consulta el tema Cómo enlazar a datos jerárquicos y crear una vista maestro y detalles.

Conversiones de datos

Puede que necesites mostrar datos en un formato que difiera del formato en el que están almacenados. A continuación se muestran algunos ejemplos:

  • Almacenamiento de un color como un valor RGBA y presentación como un nombre de cadena.
  • Almacenamiento de un número como un valor de punto flotante y presentación como un valor de moneda.
  • Almacenamiento de una fecha como DateTime y presentación en un calendario.
  • Almacenamiento de un valor null y presentación de un valor descriptivo predeterminado.

A partir de Windows 8.1, puedes mostrar un valor descriptivo predeterminado para valores de respaldo null estableciendo la propiedad TargetNullValue.

Puedes establecer un convertidor en cualquier enlace. Para personalizar el convertidor según cada escenario, crea una clase e implementa la interfaz IValueConverter. En el siguiente ejemplo se muestra cómo implementar IValueConverter.



// Custom class implements the IValueConverter interface.
public class DateToStringConverter : IValueConverter
{

    #region IValueConverter Members

    // Define the Convert method to change a DateTime object to 
    // a month string.
    public object Convert(object value, Type targetType, 
        object parameter, string language)
    {
        // value is the data from the source object.
        DateTime thisdate = (DateTime)value;
        int monthnum = thisdate.Month;
        string month;
        switch (monthnum)
        {
            case 1:
                month = "January";
                break;
            case 2:
                month = "February";
                break;
            default:
                month = "Month not found";
                break;
        }
        // Return the value to pass to the target.
        return month;

    }

    // ConvertBack is not implemented for a OneWay binding.
    public object ConvertBack(object value, Type targetType, 
        object parameter, string language)
    {
        throw new NotImplementedException();
    }

    #endregion
}


El motor de enlace llama a los métodos Convert y ConvertBack si se define el parámetro Converter para el enlace. Cuando se pasan los datos del origen, el motor de enlace llama a Convert y pasa los datos devueltos al destino. Cuando se pasan los datos del destino, el motor de enlace llama a ConvertBack y pasa los datos devueltos al origen. En el siguiente ejemplo se muestra cómo establecer el parámetro Converter.



<UserControl.Resources>
  <local:DateToStringConverter x:Key="Converter1"/>
</UserControl.Resources>

...

<TextBlock Grid.Column="0" 
  Text="{Binding Month, Converter={StaticResource Converter1}}"/>


El convertidor también tiene parámetros opcionales: ConverterLanguage, que permite especificar el lenguaje que se usará en la conversión, y ConverterParameter, que permite pasar un parámetro para la lógica de conversión. Para obtener un ejemplo en el que se use un parámetro de convertidor, consulta IValueConverter.

Si hay un error en la conversión, no inicies una excepción. En lugar de eso, devuelve DependencyProperty.UnsetValue, que detendrá la transferencia de datos.

Para mostrar un valor predeterminado cuando no se pueda resolver el origen del enlace, establece la propiedad FallbackValue. Esto sirve para controlar los errores de formato y de conversión. También resulta útil para crear un enlace con propiedades de origen que quizás no existen en todos los objetos de una colección enlazada.

Depuración de enlaces de datos

Puedes depurar enlaces de datos en Microsoft Visual Studio. Cuando ejecutas la aplicación con el depurador adjunto, los errores de enlace aparecen en la ventana Resultado en Visual Studio. Esto es útil, por ejemplo, cuando cambias el nombre de propiedades en las clases de datos pero olvidas actualizar las expresiones de enlace XAML.

Visualización de datos en el diseñador

Cuando usas el diseñador para crear una interfaz de usuario enlazada a datos, puedes mostrar datos de ejemplo para ver tamaños de diseño con precisión y ver resultados reales del cambio de tamaño automático.

Para mostrar datos en el diseñador, debes declararlo en XAML, en lugar de solo configurar la propiedad DataContext mediante programación en el código subyacente. Esto es necesario ya que cuando abres una página o control de usuario en el diseñador, no se crea la instancia. El diseñador analiza el XAML, pero no ejecuta el código subyacente. (Sin embargo, el diseñador creará una instancia de cualquier control de usuario secundario que encuentre al analizar el contenido XAML).

Puedes definir datos en XAML mediante una de las distintas técnicas, en función de si quieres mostrar los mismos datos en tiempo de ejecución y en tiempo de diseño.

Visualización de los mismos datos en tiempo de diseño y en tiempo de ejecución

Mostrar datos reales en tiempo de diseño es útil, cuando tu aplicación usa solo datos locales o cuando estás creando el prototipo de la aplicación. Por ejemplo, puedes declarar un objeto de datos como recurso y después referirte a él desde otros elementos, como se muestra en el siguiente código de Cómo enlazar a datos jerárquicos y crear una vista maestro/detalles:



<local:LeagueList x:Key="LeagueData"/>
<CollectionViewSource x:Name="Leagues"
    Source="{StaticResource LeagueData}"/>


En este caso, el analizador de XAML crea una instancia de la clase de colección LeagueList en tiempo de diseño y tiempo de ejecución, y el constructor LeagueList se rellena a sí mismo con los datos de ejemplo.

Visualización de datos distintos en tiempo de diseño y en tiempo de ejecución

Si quieres mostrar datos de ejemplo en tiempo de diseño y datos reales en tiempo de ejecución, hay algunas opciones que puedes implementar. La más simple es declarar los datos en XAML, como se mostró anteriormente, y también incluir código en la clase de datos para detectar si la llamada se está haciendo en tiempo de diseño o en tiempo de ejecución. Por ejemplo, podrías definir los métodos GetSampleData y GetRealData en la clase de datos y después usar el siguiente código en su constructor.


if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{
    GetSampleData();
}
else GetRealData();


Uso de atributos en tiempo de diseño

Otra opción para mostrar datos de ejemplo en tiempo de diseño es declararlos en XAML con diversos atributos de datos del espacio de nombres XML del diseñador. Este espacio de nombres XML, por lo general, se declara con un prefijo d: de la siguiente manera:


xmlns:d="http://schemas.microsoft.com/expression/blend/2008"


Con esta declaración, los atributos con prefijos d: se interpretan solo en tiempo de diseño y se ignoran en tiempo de ejecución. Por ejemplo, en el siguiente XAML, se usa el atributo d:Source para datos de ejemplo solo en tiempo de diseño y se usa el atributo Source para datos reales solo en tiempo de ejecución.


<CollectionViewSource
  x:Name="groupedItemsViewSource"
  Source="{Binding Groups}"
  IsSourceGrouped="true"
  ItemsPath="Items"
  d:Source="{Binding ItemGroups, 
    Source={d:DesignInstance Type=data:SampleDataSource, 
      IsDesignTimeCreatable=True}}"/>


Este código proviene de las plantillas de proyecto Aplicación de cuadrícula y Aplicación dividida, a las que puedes examinar para ver detalles sobre el origen de datos de ejemplo y para ver el código del procedimiento usado para establecer el origen de datos en tiempo de ejecución. La propiedad d:Source se aplica solo a la clase CollectionViewSource, pero para otras clases puedes usar d:DataContext del mismo modo en que usas DataContext.

La extensión de marcado d:DesignInstance indica que el origen en tiempo de diseño es una instancia creada por diseñador, en función del tipo SampleDataSource, tal como indica la opción de configuración Type. La opción de configuración IsDesignTimeCreatable indica que el diseñador creará una instancia de ese tipo directamente, lo cual es necesario para mostrar los datos de ejemplo generados por el constructor de tipo. Si no estableces este atributo (ni lo estableces en False), el diseñador, en cambio, genera y crea una instancia de una clase ligera con las mismas propiedades enlazables. Esto resulta útil si tan solo quieres que las propiedades aparezcan como destinos potenciales de enlace en el diseñador de enlace de datos, pero no te interesa mostrar datos de ejemplo.

Uso de datos de ejemplo basados en archivos

Una alternativa de d:DesignInstance es la extensión de marcado d:DesignData. Esto te permite usar datos de ejemplo definidos en archivos XAML o JSON, en lugar de datos generados mediante programación en las clases de datos. Puedes referirte a los datos de ejemplo con un marcado, como el siguiente:


<Grid d:DataContext="{Binding Source={d:DesignData Source=/Data/SampleData.xaml}}">
  <TextBlock FontSize="50" Text="{Binding Name}"/>
</Grid>


En este caso, el archivo SampleData.xaml contiene marcado como el siguiente:


<Customer xmlns="using:DemoProject.Data" Name="Customer One"/>


La declaración xmlns indica que el marcado se refiere a una clase del proyecto DemoProject.Data. Si usas archivos de datos JSON en lugar de archivos XAML, debes incluir una opción de configuración Type en el marcado d:DesignData como se muestra a continuación:


<Grid 
  xmlns:data="using:DemoProject.Data"
  d:DataContext="{Binding Source={d:DesignData 
    Source=/Data/SampleData.json, Type=data:SampleDataSource}}">
  <TextBlock FontSize="50" Text="{Binding Name}"/>
</Grid>


Temas relacionados

Guías básicas
Guía básica para crear aplicaciones de Windows en tiempo de ejecución con C# o Visual Basic
Guía básica para crear aplicaciones de Windows en tiempo de ejecución con C++
Muestras
Muestra de enlace de datos XAML
Muestra de agrupación de GridView y SemanticZoom XAML
Muestra de StorageDataSource y GetVirtualizedFilesVector
Aplicación de muestra de Reversi
Escenarios de características de muestra de Reversi: enlace de datos
Referencia
Binding
DataContext
DependencyProperty
CollectionViewSource
ObservableCollection(Of T)
DataTemplate
ControlTemplate
INotifyPropertyChanged
INotifyCollectionChanged
IValueConverter
ICustomPropertyProvider
ISupportIncrementalLoading
Conceptos
Inicio rápido: enlazar datos a controles
Cómo enlazar a datos jerárquicos y crear una vista maestro y detalles
Atributos en tiempo de diseño
Introducción a XAML
Extensión de marcado Binding
Sintaxis de property-path
Extensión de marcado RelativeSource
Introducción a las propiedades de dependencia
Propiedades de dependencia personalizadas
Introducción a las propiedades adjuntas
Referencias de recursos ResourceDictionary y XAML

 

 

Mostrar:
© 2014 Microsoft