Associação de dados com XAML
Recolher sumário
Expandir sumário

Visão geral da vinculação de dados (XAML)

[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente]

A vinculação de dados é uma maneira simples para os aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic exibirem e interagirem com os dados. O modo de exibição dos dados é separado do gerenciamento dos dados. Uma conexão, ou vinculação, entre a interface do usuário e um objeto de dados permite que os dados fluam entre ambos. Quando uma associação é estabelecida e os dados são alterados, os elementos da interface do usuário associados aos dados podem exibir as alterações automaticamente. Da mesma forma, as alterações feitas pelo usuário em um elemento da interface do usuário podem ser salvas no objeto de dados. Por exemplo, se o usuário editar o valor em TextBox, o valor de dados subjacente será atualizado automaticamente para refletir essa alteração.

Alguns cenários de associação comuns são a associação de ListBox a uma lista de cabeçalhos ou Image à foto do usuário atual.

Este tópico descreve detalhadamente os recursos de vinculação de dados. Para ler uma breve introdução aos conceitos, consulte o Guia de início rápido: vinculando dados a controles.

Exemplos de códigoEste tópico usa exemplos de código simples e partes de amostras para ilustrar conceitos básicos de vinculação de dados. Para obter amostras completas, veja:

Para ver um exemplo de ponta a ponta que usa a vinculação de dados de forma extensiva, confira o Aplicativo de exemplo Reversi. Para saber mais, veja Reversi, um jogo da Windows Store em XAML, C# e C++ e a seção de vinculação de dados de Saiba como o aplicativo de exemplo Reversi usa os recursos do aplicativo da Windows Store.

Para obter outros exemplos de C++, veja Criar um aplicativo usando C++.

Mapa: como este tópico está relacionado aos outros? Veja:

Conectando elementos da interface do usuário aos dados

Cada associação inclui:

  • A origem da associação, que é o objeto com os dados que você deseja renderizar.
  • O destino da associação, que é o DependencyProperty de FrameworkElement para renderização dos dados.
  • O objeto Binding, que transfere os dados entre a origem e o destino e pode reformatá-los usando um conversor de valor opcional.

A origem pode ser:

  • Qualquer objeto CLR (Common Language Runtime), inclusive o próprio elemento de destino ou outros elementos da interface do usuário. Se o destino for um modelo de dados, a origem poderá ser o elemento da interface do usuário ao qual o modelo é aplicado. As classes definidas em C# e Visual Basic produzem objetos CLR. Por isso, eles são associáveis por padrão.
  • Qualquer objeto do Tempo de Execução do Windows de um tipo que tenha BindableAttribute ou implemente ICustomPropertyProvider. As classes definidas em C++ produzem objetos do Tempo de Execução de Windows. Por isso, eles necessitam de uma destas abordagens para serem associáveis.

O destino pode ser qualquer DependencyProperty de FrameworkElement.

O mecanismo de associação obtém informações do objeto Binding referentes ao seguinte:

  • Os objetos de origem e de destino.
  • A direção do fluxo de dados. Especifique a direção definido a propriedade Binding.Mode.
  • O conversor de valor, se houver um. Especifique um conversor de valor definindo a propriedade Converter como uma instância de uma classe que implementa IValueConverter.
  • Outras configurações, como FallbackValue e TargetNullValue. Veja a classe Binding para obter a lista completa de propriedades.

Por exemplo, a propriedade Foreground de TextBox pode ser associada a SolidColorBrush para que a cor do texto possa ser alterada com base nos dados. Nesse cenário, a propriedade Foreground é o destino, e o objeto SolidColorBrush é a origem para a associação.

O exemplo a seguir mostra como associar a cor Foreground de um TextBox a um SolidColorBrush. A origem da associação é uma propriedade da classe MyColors, que é descrita mais adiante neste tópico.



<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;


Observação  Este exemplo usa a sintaxe do atributo XAML para criar a associação. Você também pode usar a sintaxe do elemento do objeto para criar a associação em XAML. Para saber mais, veja Visão geral de XAML.
 

A associação é criada em XAML usando a sintaxe {Binding ...}. A origem é definida em código configurando a propriedade DataContext referente a TextBox.

O contexto dos dados é herdado. Se você definir o contexto dos dados em um elemento pai, seus respectivos filhos usarão o mesmo contexto dos dados. Um elemento filho pode substituir esse comportamento definindo a propriedade Source em seu objeto de associação ou definindo seu DataContext. Essa substituição se aplica aos filhos do elemento filho.

A definição do contexto dos dados é útil quando você quer ter várias associações que usam a mesma origem. Para definir a origem para uma única associação, defina a propriedade Source no objeto Binding.

Você também pode usar a propriedade ElementName ou a propriedade RelativeSource para especificar a origem da associação. A propriedade ElementName é útil quando você está associando a outros elementos no aplicativo, por exemplo, ao usar um controle deslizante para ajustar a largura de um botão. A propriedade RelativeSource é útil quando a associação é especificada em ControlTemplate. Para obter mais informações, consulte Extensão de marcação Binding e Extensão de marcação RelativeSource.

Você pode associar a uma propriedade do objeto de origem definindo a propriedade Binding.Path. A propriedade Path dá suporte a várias opções de sintaxe para associação a propriedades aninhadas, propriedades anexadas e indexadores de inteiros e cadeias de caracteres. Para saber mais, veja Sintaxe do Property-path. A associação a indexadores de inteiros tem o mesmo efeito da associação a propriedades dinâmicas, mas sem implementar ICustomPropertyProvider.

Se você associar um controle de texto a um valor que não seja uma cadeia, o mecanismo de vinculação de dados converterá o valor a uma cadeia. Se o valor for um tipo de referência, o mecanismo de vinculação de dados recuperará o valor da cadeia chamando ICustomPropertyProvider.GetStringRepresentation ou IStringable.ToString se disponível e, de outra forma, chamará Object.ToString. Observe, porém, que esse mecanismo ignora qualquer implementação de ToString que oculte a implementação da classe base. Implementações de subclasse devem substituir o método ToString da classe base em vez disso. Da mesma forma, nos idiomas não gerenciados, todos os objetos gerenciados parecem implementar ICustomPropertyProvider e IStringable. Porém, todas as chamadas para GetStringRepresentation e IStringable.ToString são roteadas para Object.ToString ou para uma substituição desse método e nunca para uma nova implementação de ToString que oculte a implementação da classe base.

No geral, o exemplo anterior faz com que o mecanismo de associação crie uma associação, que é unidirecional por padrão. Ele conecta a propriedade Foreground do TextBox à propriedade Brush1 do objeto textcolor.

Criando associações em código

Você também pode conectar elementos da interface do usuário aos dados usando código de procedimentos em vez de XAML. Para fazer isso, crie um novo objeto Binding, defina as propriedades apropriadas, depois chame FrameworkElement.SetBinding ou BindingOperations.SetBinding. A criação de associações de forma programática é útil quando você deseja escolher os valores da propriedade de associação no tempo de execução ou compartilhar uma única associação entre vários controles. Observe, porém, que você não pode alterar os valores da propriedade de associação depois que chamar SetBinding.

O exemplo a seguir mostra como implementar a associação anterior em 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);


Direção do fluxo de dados

Cada associação tem uma propriedade Mode, que determina como e quando os dados fluem. Os aplicativos do Tempo de Execução do Windows em C++, C# ou Visual Basic podem usar três tipos de associação:

  • As associações OneTime atualizam o destino com os dados de origem quando a associação é criada.
  • As associações OneWay atualizam o destino com os dados de origem quando a associação é criada e sempre que os dados são alterados. Este é o modo padrão.
  • As associações TwoWay atualizam tanto o destino quanto a origem quando qualquer um dos dois é alterado. Uma exceção a esse comportamento é se alterações ao TextBox.Text não forem enviadas a uma origem associada após cada pressionamento de teclas pelo usuário, a menos que Binding.UpdateSourceTrigger esteja definido como PropertyChanged. Por padrão, as alterações são enviadas apenas quando a TextBox perde o foco.

Você pode alterar o comportamento das associações TwoWay de forma que os valores não sejam copiados automaticamente na origem, mas apenas quando você quiser. Para fazer isso, defina a propriedade Binding.UpdateSourceTrigger como Explicit. Depois, você pode chamar GetBindingExpression no destino para obter um objeto BindingExpression e chamar BindingExpression.UpdateSource para atualizar de forma programática a fonte de dados.

Notificação de alterações

Para que as alterações feitas no objeto de origem se propaguem para o destino, a origem deve implementar a interface INotifyPropertyChanged. INotifyPropertyChanged contém o evento PropertyChanged. Esse evento informa ao mecanismo de associação que a origem foi alterada, para que ele possa atualizar o valor de destino. Para C# ou Microsoft Visual Basic, você implementa System.ComponentModel.INotifyPropertyChanged. Para extensões de componentes Visual C++ (C++/CX), você implementa Windows::UI::Xaml::Data::INotifyPropertyChanged.

Nesse exemplo, a classe MyColors implementa a interface INotifyPropertyChanged para a associação 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));
        }
    }
}


Você pode disparar o evento PropertyChanged para indicar que todas as propriedades não indexadas no objeto foram alteradas usando um valor PropertyChangedEventArgs.PropertyName de String.Empty. Observe que não é possível usar null (Nothing no Visual Basic) para isso, assim como é possível no Windows Presentation Foundation (WPF) e no Microsoft Silverlight.

Observação  Para C# ou Visual Basic, você usa System.ComponentModel.PropertyChangedEventArgs. Para C++/CX, você usa Windows::UI::Xaml::Data::PropertyChangedEventArgs.
 

Você também pode usar a notificação de alterações com propriedades de indexador. Você pode disparar o evento PropertyChanged para indicar que as propriedades no indexador do objeto foram alteradas com um valor PropertyChangedEventArgs.PropertyNamede "Item[ indexer]" para indexadores específicos (em que indexer é o valor do índice), ou um valor de "Item[]" para todos os indexadores.

Associando a coleções

Um objeto de origem de associação pode ser tratado como um único objeto cujas propriedades contêm dados ou como uma coleção de objetos. Por exemplo, talvez você queira exibir uma lista de itens, como faturas mensais de cartão de crédito. Para fazer isso, use ItemsControl e use DataTemplate para exibir cada item em uma coleção.



<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}"/>


Em código C# e Visual Basic, você pode popular e associar a List(Of T) para exibir uma coleção sem alteração. Se itens forem adicionados à coleção e removidos dela em tempo de execução, e você quiser que o destino atualize ItemsSource quando isso ocorrer, use ObservableCollection(Of T). Em código C++, você pode preencher e associar a instâncias de Vector<T> para coleções com e sem alteração. Para associar às suas próprias classes de coleção, use a diretriz da tabela a seguir.

O sistema de vinculação de dados oferece suporte aos seguintes cenários de associação.

Carregando dados de forma incremental

Você pode associar controles de lista a fontes de dados arbitrariamente grandes e ainda assim obter um alto desempenho, usando o carregamento incremental. Por exemplo, você pode associar controles de lista a resultados de consulta de imagens do Bing sem precisar carregar todos os resultados de uma vez. Em vez disso, você carrega apenas alguns resultados imediatamente e carrega resultados adicionais conforme o necessário. Para oferecer suporte ao carregamento incremental, você deve implementar ISupportIncrementalLoading em uma fonte de dados que ofereça suporte à notificação de alterações de coleção. Quando o mecanismo de vinculação de dados solicitar mais dados, a fonte de dados deverá fazer as solicitações apropriadas, integrar os resultados e, depois, enviar as notificações apropriadas para atualizar a interface do usuário. Para saber mais, veja Exemplo de vinculação de dados XAML .

Associando a listas de pastas e de arquivos

Observação  

Somente aplicativos da Windows Store. Você pode usar as APIs do namespace Windows.Storage para recuperar dados de pastas e arquivos. No entanto, os diversos métodos GetFilesAsync, GetFoldersAsync e GetItemsAsync não retornam valores adequados para a associação a controles de lista. Em vez disso, você deve associar os valores de retorno dos métodos GetVirtualizedFilesVector, GetVirtualizedFoldersVector e GetVirtualizedItemsVector da classe FileInformationFactory. O exemplo de código a seguir, da Amostra de StorageDataSource e GetVirtualizedFilesVector, mostra o padrão de uso típico.


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;
}


Observação  

Somente aplicativos da Windows Store. Você normalmente usará essa abordagem para criar um modo de exibição somente leitura das informações de arquivos e de pastas. Você pode criar associações bidirecionais às propriedades de arquivo e pasta para, por exemplo, permitir que os usuários classifiquem uma música em um modo de exibição de músicas. Porém, as alterações não serão persistidas até que você chame o método SavePropertiesAsync apropriado (por exemplo, MusicProperties.SavePropertiesAsync). Você deve confirmar as alterações quando o item perde o foco porque isso ativa uma redefinição de seleção.

Observe que a associação bidirecional que usa essa técnica funciona apenas em locais indexados, por exemplo, em Música. Você pode determinar se um local é indexado chamando o método FolderInformation.GetIndexedStateAsync.

Observe também que um vetor virtualizado pode retornar null para alguns itens antes de ele preencher seu valor. Por exemplo, você deve verificar se há null antes de usar o valor SelectedItem de um limite de controle de lista para um vetor virtualizado ou use SelectedIndex.

Agrupando dados e controlando o item atual

Você também pode associar a instâncias da classe CollectionViewSource para exibir coleções de coleções e controlar o item atual em vários modos de exibição. Normalmente você define CollectionViewSource como um recurso XAML e associa a ele usando a extensão de marcação StaticResource. Defina sua propriedade Source em code-behind a um tipo de coleção com suporte.

Todos os controles que você associar à mesma CollectionViewSource terão sempre o mesmo item atual, e todas as associações com as configurações Path associarão automaticamente às propriedades do item atual. Você pode acessar o item atual de forma programática usando a propriedade ICollectionView.CurrentItem do valor de propriedade CollectionViewSource.View.

Se os itens na coleção forem coleções de verdade ou então objetos que contêm coleções, você poderá exibir as coleções como grupos dentro da coleção maior. Para fazer isso, defina a propriedade IsSourceGrouped como true. Se os itens contiverem coleções mas não forem coleções de verdade, você também precisará definir a propriedade ItemsPath como sendo o nome da propriedade de coleção. Por exemplo, se você associar a uma coleção CustomerList de objetos Customer e a classe Customer tiver uma propriedade Orders que seja uma coleção de objetos Order, você poderá agrupar os pedidos por cliente usando o seguinte XAML.


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


Você poderá então criar um modelo de cabeçalho de grupo que associe a propriedades da classe Customer e um modelo de item que associe a propriedades da classe Order. Você também pode acessar os grupos de forma programática usando a propriedade CollectionViewSource.CollectionGroups.

O exemplo de código a seguir demonstra a maneira de associar um controle ListBox aos resultados de uma consulta LINQ de agrupamento. Nesse exemplo, uma coleção de equipes está agrupada por cidade e é exibida com o nome da cidade nos cabeçalhos dos grupos. Isso é indicado pelo caminho de propriedade "Key" na referência ao valor Key do grupo. Para obter a listagem de códigos completa, veja o exemplo de vinculação de dados. Para obter outro exemplo de código semelhante que mostre agrupamento, veja a amostra de GridView agrupado.


<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;


Outra opção ao associar a dados em vários níveis, como categorias com subcategorias, é exibir os níveis como uma série de listas. Assim, uma seleção em uma lista afeta o conteúdo das listas subsequentes. Você pode manter as listas sincronizadas associando cada uma delas à sua própria CollectionViewSource e reunindo as instâncias CollectionViewSource em uma cadeia. Para saber mais, consulte Como associar a dados hierárquicos e criar um modo de exibição mestre/detalhado.

Conversões de dados

Talvez seja necessário exibir dados em um formato diferente de como eles são armazenados. Alguns exemplos são estes:

  • Armazenar uma cor como um valor RGBA, mas exibi-la como um nome de cadeia de caracteres.
  • Armazenar um número como um valor de ponto flutuante, mas exibi-lo como um valor de moeda.
  • Armazenar uma data como DateTime, mas exibi-la em um calendário.
  • Armazenar um valor null, mas exibir um valor padrão amigável.

A partir do Windows 8.1, você pode exibir um valor padrão amigável para os valores de backup de null definindo a propriedade TargetNullValue.

Você pode definir um conversor em qualquer associação. Para personalizar o conversor para cada cenário, crie uma classe e implemente a interface IValueConverter. O exemplo a seguir mostra como 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
}


O mecanismo de associação chamará os métodos Convert e ConvertBack se o parâmetro Converter for definido para a associação. Quando os dados forem repassados da origem, o mecanismo de associação chamará Convert e repassará os dados retornados ao destino. Quando os dados forem repassados do destino, o mecanismo de associação chamará ConvertBack e repassará os dados retornados à origem. O exemplo a seguir mostra como definir o parâmetro Converter.



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

...

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


O conversor também tem parâmetros opcionais: ConverterLanguage, que permite especificar o idioma que será usado na conversão, e ConverterParameter, que permite repassar um parâmetro para a lógica de conversão. Para obter um exemplo de uso de um parâmetro de conversor, consulte IValueConverter.

Se houver erro na conversão, não emita uma exceção. Em vez disso, retorne DependencyProperty.UnsetValue, que interromperá a transferência de dados.

Para exibir um valor padrão que apareça sempre que a origem da associação não puder ser resolvida, defina a propriedade FallbackValue. Isso é útil para lidar com erros de conversão e formatação. E também para associar propriedades da origem que talvez não existam em todos os objetos em uma coleção associada.

Depurando associações de dados

Você pode depurar associações de dados no Microsoft Visual Studio. Quando você executa o aplicativo com o depurador anexado, os possíveis erros de associação aparecem na janela Saída do Visual Studio. Isso é útil, por exemplo, quando você renomeia as propriedades em suas classes de dados, mas se esquece de atualizar as expressões de associação XAML.

Exibindo dados no designer

Quando você usa o designer para criar uma interface do usuário com dados associados, é possível exibir dados de amostra para visualizar os tamanhos do layout com precisão e ver resultados realísticos do dimensionamento automático.

Para exibir os dados no designer, você deve declará-los em XAML em vez de apenas configurar a propriedade DataContext de forma programática em code-behind. Isso é necessário, porque quando você abre uma página ou controle de usuário no designer, ele não é instanciado. O designer analisa seu XAML, mas não executa seu code-behind. (Entretanto, o designer instanciará quaisquer controles de usuário filho que encontrar quando analisar o conteúdo XAML.)

Você pode definir os dados em XAML usando uma das diversas técnicas, dependendo do fato de você querer exibir os mesmos dados na hora da execução e na fase do design.

Exibindo os mesmos dados na hora da execução e na fase do design

A exibição de dados reais na fase do design é útil quando o aplicativo usa apenas dados locais ou quando o aplicativo é um protótipo. Por exemplo, você pode declarar um objeto de dados como um recurso e, depois, fazer referência a ele a partir de outros elementos, conforme mostrado no seguinte código de Como associar a dados hierárquicos e criar um modo de exibição mestre/detalhado:



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


Nesse caso, o analisador de XAML instancia a classe de coleção LeagueList na fase do design e na hora da execução e o construtor LeagueList é automaticamente preenchido com os dados de amostra.

Exibindo dados diferentes na hora da execução e na fase do design

Se quiser exibir dados de amostra na fase do design e dados reais na hora da execução, você terá algumas opções. A opção mais simples é declarar os dados em XAML como mostrado anteriormente e também incluir código na classe de dados para detectar se eles estão sendo chamados na fase do design ou na hora da execução. Por exemplo, você pode definir os métodos GetSampleData e GetRealData na classe de dados e, depois, usar o seguinte código no instrutor.


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


Usando atributos da fase do design

Outra opção para exibir os dados de amostra na fase do design é declará-los em XAML usando vários atributos de dados do namespace de XML do designer. Esse namespace de XML costuma ser declarado com um prefixo d: como este:


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


Com essa declaração, os atributos com prefixos d: são interpretados apenas na fase do design e são ignorados na hora da execução. Por exemplo, no XAML a seguir, o atributo d:Source é usado para dados de amostra somente da fase do design e o atributo Source é usado para os dados reais somente da hora da execução.


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


Esse código é proveniente dos modelos de projeto Aplicativo de Grade e Aplicativo Dividido, que você pode examinar para ver os detalhes do exemplo de fonte dos dados e para obter o código de procedimentos usado para estabelecer a fonte de dados do tempo de execução. A propriedade d:Source aplica-se apenas à classe CollectionViewSource, mas, para as demais classes, você pode usar d:DataContext da mesma maneira que usa DataContext.

A extensão de marcação d:DesignInstance indica que a fonte da fase do design é uma instância criada pelo designer com base no tipo SampleDataSource, como indicado pela configuração Type. A configuração IsDesignTimeCreatable indica que o designer instanciará esse tipo diretamente, o que é necessário para exibir os dados de amostra gerados pelo construtor de tipos. Se você não definir esse atributo (ou se ele for definido como False), em vez disso, o designer gera e instancia uma classe leve com as mesmas propriedades associáveis. Isso é útil apenas quando você quer que as propriedades apareçam como possíveis destinos de associação no designer de vinculação de dados, mas você não se preocupa em exibir os dados de amostra.

Usando dados de amostra baseados em arquivo

Uma alternativa para d:DesignInstance é extensão de marcação d:DesignData. Isso permite que você use os dados de amostra definidos em XAML, ou arquivos JSON, em vez de usar os dados gerados de forma programática nas suas classes de dados. Você pode fazer referência aos dados de amostra usando marcação como a seguir:


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


Nesse caso, o arquivo SampleData.xaml contém marcação como a seguir:


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


A declaração xmlns indica que a marcação faz referência a uma classe no projeto DemoProject.Data. Se usar arquivos de dados JSON em vez de arquivos XAML, você deve incluir uma configuração de Type na marcação d:DesignData, como mostrado aqui:


<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>


Tópicos relacionados

Mapas
Mapa de aplicativos do Tempo de Execução do Windows em C# ou Visual Basic
Mapa de aplicativos do Tempo de Execução do Windows em C++
Exemplos
Exemplo de vinculação de dados XAML
Exemplo de SemanticZoom e agrupamento de GridView em XAML
Amostra de StorageDataSource e GetViertualizedFilesVector
Aplicativo de exemplo Reversi
Cenários de recursos de exemplo de Reversi: vinculação de dados
Referência
Binding
DataContext
DependencyProperty
CollectionViewSource
ObservableCollection(Of T)
DataTemplate
ControlTemplate
INotifyPropertyChanged
INotifyCollectionChanged
IValueConverter
ICustomPropertyProvider
ISupportIncrementalLoading
Conceitos
Guia de início rápido: vinculando dados a controles
Como associar a dados hierárquicos e criar um modo de exibição mestre/detalhado
Atributos do tempo de design
Visão geral de XAML
Extensão de marcação de associação
Sintaxe de Property-path
Extensão de marcação RelativeSources
Visão geral das propriedades de dependência
Propriedades de dependência personalizadas
Visão geral das propriedades anexadas
Referências aos recursos ResourceDictionary e XAML

 

 

Mostrar:
© 2017 Microsoft