Inicio rápido: enlazar datos a controles (XAML)

En este tema se muestra cómo enlazar un control a un solo elemento o enlazar un control de lista a una colección de elementos en una aplicación de la Tienda Windows con C++, C# o Visual Basic. Además, se muestra cómo personalizar la visualización de los elementos del control, implementar una vista de detalles basada en una selección y convertir datos para mostrarlos. Para obtener información más detallada, consulta Enlace de datos con XAML.

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

Requisitos previos

En este tema se da por hecho que sabes crear una aplicación básica de Windows en tiempo de ejecución con Microsoft Visual Basic, Microsoft Visual C# o Microsoft Visual C++. Si quieres obtener instrucciones para crear tu primera aplicación de Windows en tiempo de ejecución, consulta el tema sobre cómo crear tu primera aplicación de la Tienda Windows con C# o Visual Basic.

Enlace de un control a un solo elemento

Un enlace de datos consta de un destino y un origen. El destino suele ser una propiedad de un control, mientras que el origen normalmente es una propiedad de un objeto de datos. Para obtener información sobre los requisitos de origen y de destino, consulta Enlace de datos con XAML.

A continuación se muestra un ejemplo de enlace de un control a un solo elemento. El destino es la propiedad Text de un control de cuadro de texto. El origen es una clase Recording simple de música.



<Grid x:Name="LayoutRoot" Background="#FF0C0C0C">
  <TextBox x:Name="textBox1" Text="{Binding}" FontSize="30"
    Height="120" Width="440" IsReadOnly="True"
    TextWrapping="Wrap" AcceptsReturn="True" />
</Grid>




// Constructor
public MainPage()
{
    InitializeComponent();
    
    // Set the data context to a new Recording.
    textBox1.DataContext = new Recording("Chris Sells", "Chris Sells Live",
        new DateTime(2008, 2, 5));
}

// A simple business object
public class Recording
{
    public Recording() { }

    public Recording(string artistName, string cdName, DateTime release)
    {
        Artist = artistName;
        Name = cdName;
        ReleaseDate = release;
    }

    public string Artist { get; set; }
    public string Name { get; set; }
    public DateTime ReleaseDate { get; set; }

    // Override the ToString method.
    public override string ToString()
    {
        return Name + " by " + Artist + ", Released: " + ReleaseDate.ToString("d");
    }
}

El código anterior produce un resultado similar a la siguiente ilustración.

enlace de un cuadro de texto

Para mostrar una grabación de música en un cuadro de texto, la propiedad Text del control se establece en un Binding mediante una extensión de marcado. En este ejemplo, el Mode es OneWay de manera predeterminada, lo que significa que los datos se recuperan del origen, pero los cambios no se vuelven a propagar al origen.

La clase Recording tiene tres propiedades públicas y una invalidación de método ToString. Las propiedades son Artist, Name y ReleaseDate. El método ToString es significativo, porque si no se especifica ningún formato, se llama al método ToString en un objeto enlazado con fines de visualización. La propiedad Binding.Source para el enlace no se establece directamente. En lugar de eso, se establece la propiedad DataContext para el control TextBox en un nuevo objeto Recording.

Enlace de un control a una colección de objetos

En el ejemplo anterior se demuestra la sintaxis que usas para enlazar datos a controles, pero no es muy realista. Un escenario más común es enlazar una colección de objetos profesionales. En C# y Visual Basic, la clase ObservableCollection<T> genérica es una buena elección de colección para el enlace de datos, porque implementa las interfaces INotifyPropertyChanged y INotifyCollectionChanged. Estas interfaces proporcionan notificación de cambios a los controles enlazados cuando cambia un elemento de la lista o cuando cambia una propiedad de la lista en sí. Si quieres que los controles enlazados se actualicen con los cambios en las propiedades de objetos de la colección, el objeto profesional también debe implementar INotifyPropertyChanged. Para obtener información acerca del enlace en C++, consulta Enlace de datos con XAML.

En el siguiente ejemplo se enlaza una colección de objetos Recording de música a un ComboBox. Para probar este ejemplo, haz clic en la flecha abajo del cuadro combinado para ver la lista de grabaciones enlazadas.



<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
        Foreground="Black" FontSize="30" Height="50" Width="780"/>
</Grid>



public ObservableCollection<Recording> MyMusic = new ObservableCollection<Recording>();

public Page()
{
    InitializeComponent();

    // Add items to the collection.
    MyMusic.Add(new Recording("Chris Sells", "Chris Sells Live",
        new DateTime(2008, 2, 5)));
    MyMusic.Add(new Recording("Luka Abrus",
        "The Road to Redmond", new DateTime(2007, 4, 3)));
    MyMusic.Add(new Recording("Jim Hance",
        "The Best of Jim Hance", new DateTime(2007, 2, 6)));

    // Set the data context for the combo box.
    ComboBox1.DataContext = MyMusic;
}

El código anterior produce un resultado similar a la siguiente ilustración.

enlace de un cuadro combinado

Para mostrar las grabaciones de música en el ComboBox, la propiedad ItemsSource del control se establece en Binding y la propiedad DataContext del control ComboBox se establece en la colección de objetos Recording, que proporciona el origen para el enlace. Se crea un ComboBoxItem para cada elemento de la colección. Se llama automáticamente a ToString en cada objeto Recording para mostrarlo en el elemento de cuadro combinado.

Visualización de elementos en un control con una plantilla de datos

Puedes mostrar elementos en una lista mediante el método ToString del elemento. Sin embargo, un escenario más común es proporcionar una visualización personalizada de los elementos enlazados con datos mediante una DataTemplate. Una DataTemplate te permite personalizar la manera en que se muestran los elementos en un control. Generalmente, estableces la plantilla de datos mediante la propiedad ContentTemplate de un control de contenido o la propiedad ItemTemplate de un control de elementos.

En el siguiente ejemplo se muestra la misma lista de grabaciones enlazadas a un cuadro combinado mediante una plantilla de datos. Un cuadro combinado es un ItemsControl, lo que significa que debes establecer una plantilla de datos para cada elemento al establecer su propiedad ItemTemplate en una plantilla de datos. Para probar este ejemplo, haz clic en la flecha abajo para ver la lista de grabaciones. Observa cómo difiere el aspecto de las grabaciones del ejemplo anterior. El intérprete y el nombre de CD se muestran en un formato personalizado.



<ComboBox x:Name="ComboBox1" ItemsSource="{Binding}"
  Foreground="Black" FontSize="30" Height="50" Width="450">
  <ComboBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal" Margin="2">
        <TextBlock Text="Artist:" Margin="2" />
        <TextBlock Text="{Binding Artist}" Margin="2" />
        <TextBlock Text="CD:" Margin="10,2,0,2" />
        <TextBlock Text="{Binding Name}" Margin="2" />
      </StackPanel>
    </DataTemplate>
  </ComboBox.ItemTemplate>
</ComboBox>

El código anterior produce un resultado similar a la siguiente ilustración.

uso de una plantilla de datos

En XAML, puedes ver la definición de plantilla de datos. La plantilla de datos contiene un StackPanel con cuatro controles TextBlock. El panel de apilamiento tiene una orientación horizontal para que los cuatro controles de bloque de texto aparezcan en paralelo. Dos de los controles TextBlock están enlazados a las propiedades Artist y Name de un objeto Recording. Los otros dos controles TextBlock muestran texto estático. Para cada elemento enlazado, el enlace proporciona la ruta a la propiedad en el objeto Recording. Al igual que en el ejemplo anterior, este enlace depende del contexto de datos que se establece en la lista de grabaciones.

Este código XAML usa la sintaxis de elemento de propiedad. Para obtener más información acerca de la sintaxis XAML, consulta Inicio rápido: crear una interfaz de usuario con XAML. Para obtener más información acerca del diseño de controles, consulta Inicio rápido: definir diseños.

Agregar una vista de detalles

Para mostrar los detalles de un elemento cuando se selecciona de una colección, debes crear la interfaz de usuario adecuada y enlazarla a los datos que quieres que muestre. Además, debes usar un CollectionViewSource como contexto de datos para permitir que la vista de detalles se enlace al elemento actual.

En el siguiente ejemplo se muestra la misma lista de grabaciones, pero en este caso la lista es el origen de datos de una instancia de CollectionViewSource. El contexto de datos de la página entera o el control de usuario se establece en el origen de la vista de la colección, y la vista de detalles y el cuadro combinado heredan el contexto de datos. Esto permite que el cuadro combinado se enlace a la colección y muestre la misma lista de elementos mientras la vista de detalles se enlaza automáticamente al elemento actual. La vista de detalles no necesita enlazarse de forma explícita al elemento actual porque el origen de la vista de la colección proporciona automáticamente el nivel adecuado de datos.

Para probar este ejemplo, haz clic en la flecha abajo y selecciona diferentes grabaciones. Observa que el intérprete, el nombre de CD y la fecha de lanzamiento aparecen en una vista de detalles debajo del cuadro combinado.



<!--The UI for the details view-->
<StackPanel x:Name="RecordingDetails">
  <TextBlock Text="{Binding Artist}" FontWeight="Bold" FontSize="30" />
  <TextBlock Text="{Binding Name}" FontStyle="Italic" FontSize="30" />
  <TextBlock Text="{Binding ReleaseDate}" FontSize="30" />
</StackPanel>



// Set the DataContext on the parent object instead of the ComboBox
// so that both the ComboBox and details view can inherit it.  
// ComboBox1.DataContext = MyMusic;
this.DataContext = new CollectionViewSource { Source = MyMusic };

El código anterior produce un resultado similar a la siguiente ilustración.

mostrar una vista de detalles

En este ejemplo, se agrega un StackPanel al control del usuario que contiene el cuadro combinado existente. Después hay un panel de apilamiento que contiene tres bloques de texto para mostrar detalles de las grabaciones. La propiedad Text de cada bloque de texto está enlazada a una propiedad en el objeto Recording.

Conversión de datos para mostrarlos en controles

Si quieres formatear y mostrar un tipo que no sea de cadena en un control, como un TextBox, puedes usar un convertidor. Por ejemplo, puedes mostrar una etiqueta y una fecha con formato en lugar de mostrar solo la fecha.

En el siguiente ejemplo se muestra una implementación de convertidor para la fecha de lanzamiento en la lista de grabaciones. Para probar este ejemplo, haz clic en la flecha abajo y selecciona diferentes grabaciones. Observa que la fecha de lanzamiento en la lista desplegable y la vista de detalles se muestran con un formato personalizado.



<UserControl x:Class="TestDataBindingQS.Page2"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:local="using:TestDataBindingQS"
  mc:Ignorable="d"
  d:DesignHeight="768" d:DesignWidth="1366">

  <UserControl.Resources>
    <local:StringFormatter x:Key="StringConverter"/>
  </UserControl.Resources>

  <Grid x:Name="LayoutRoot" Background="#FF0C0C0C">

    <StackPanel Width="750" Height="200"
      VerticalAlignment="Center" HorizontalAlignment="Center">
    
      <ComboBox x:Name="ComboBox1" ItemsSource="{Binding}" 
        Foreground="Black" FontSize="30" Height="50" Width="750">
        <ComboBox.ItemTemplate>
          <DataTemplate>
            <StackPanel Orientation="Horizontal" Margin="2">
              <TextBlock Text="Artist:" Margin="2" />
              <TextBlock Text="{Binding Artist}" Margin="2" />
              <TextBlock Text="CD:" Margin="10,2,0,2" />
              <TextBlock Text="{Binding Name}" Margin="2" />
            </StackPanel>
          </DataTemplate>
        </ComboBox.ItemTemplate>
      </ComboBox>

      <!--The UI for the details view-->
      <StackPanel x:Name="RecordingDetails">
        <TextBlock Text="{Binding Artist}" FontSize="30" FontWeight="Bold" />
        <TextBlock Text="{Binding Name}" FontSize="30" FontStyle="Italic" />
        <TextBlock Text="{Binding ReleaseDate,
          Converter={StaticResource StringConverter},
          ConverterParameter=Released: \{0:d\}}" FontSize="30"  />
      </StackPanel>

    </StackPanel>
  
  </Grid>

</UserControl>



public class StringFormatter : IValueConverter
{
    // This converts the value object to the string to display.
    // This will work with most simple types.
    public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        // Retrieve the format string and use it to format the value.
        string formatString = parameter as string;
        if (!string.IsNullOrEmpty(formatString))
        {
            return string.Format(culture, formatString, value);
        }

        // If the format string is null or empty, simply
        // call ToString() on the value.
        return value.ToString();
    }

    // No need to implement converting back on a one-way binding
    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

El código anterior produce un resultado similar a la siguiente ilustración.

visualización de una fecha con formato personalizado

Un convertidor es una clase que deriva de la interfaz IValueConverter. IValueConverter tiene dos métodos: Convert y ConvertBack. Para obtener un enlace unidireccional del origen de datos al destino de enlace, solo tienes que implementar el método Convert. En este ejemplo, el convertidor es bastante genérico. Puedes pasar el formato de cadena deseado como un parámetro, y el convertidor usará el método String.Format para realizar la conversión. Si no se pasa una cadena de formato, el convertidor devuelve el resultado de la llamada a ToString en el objeto.

Una vez que implementas el convertidor, creas una instancia de la clase del convertidor e indicas a los enlaces que usen esta instancia. En este ejemplo, esto se realiza en XAML. Se crea una instancia del convertidor como un recurso estático y se le asigna una clave. La clave se usa cuando la propiedad del convertidor se establece en el enlace.

Para más información acerca de cómo convertir datos para mostrarlos en controles, consulta IValueConverter.

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++
Ejemplos
Muestra de enlace de datos XAML
Muestra de agrupación de GridView y SemanticZoom XAML
Muestra de StorageDataSource y GetVirtualizedFilesVector
Referencia
Binding
DataContext
DependencyProperty
CollectionViewSource
IValueConverter
INotifyPropertyChanged
INotifyCollectionChanged
DataTemplate
Conceptos
Enlace de datos con XAML
Cómo enlazar a datos jerárquicos y crear una vista maestro y detalles
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
Crear la primera aplicación de la Tienda Windows con C# o Visual Basic

 

 

Mostrar:
© 2015 Microsoft