Compartilhar via


Extensão de marcação {x:Bind}

Observação Para obter informações gerais sobre como usar a associação de dados em seu aplicativo com {x:Bind} (e para uma comparação completa entre {x:Bind} e {Binding}), consulte Associação de dados em detalhes.

A extensão de marcação {x:Bind} , nova para Windows 10, é uma alternativa a {Binding}. {x:Vincular} é executado em menos tempo e menos memória do que {Binding} e dá suporte a uma melhor depuração.

Em tempo de compilação XAML, {x:Bind} é convertido em código que obterá um valor de uma propriedade em uma fonte de dados e o definirá na propriedade especificada na marcação. Opcionalmente, o objeto de associação pode ser configurado para observar alterações no valor da propriedade da fonte de dados e se atualizar com base nessas alterações (Mode="OneWay"). Opcionalmente, ele também pode ser configurado para enviar alterações em seu próprio valor de volta para a propriedade source (Mode="TwoWay").

Os objetos de associação criados por {x:Bind} e {Binding} são em grande parte funcionalmente equivalentes. Mas {x:Bind} executa código de finalidade especial, que ele gera em tempo de compilação, e {Binding} usa inspeção de objeto de runtime de uso geral. Consequentemente, as associações {x:Bind} (geralmente chamadas de associações compiladas) têm ótimo desempenho, fornecem validação em tempo de compilação de suas expressões de associação e dão suporte à depuração, permitindo que você defina pontos de interrupção nos arquivos de código gerados como a classe parcial para sua página. Esses arquivos podem ser encontrados em sua pasta obj, com nomes como (para C#) <view name>.g.cs.

Dica

{x:Vincular} tem um modo padrão de OneTime, ao contrário de {Binding}, que tem um modo padrão de OneWay. Isso foi escolhido por motivos de desempenho, pois o uso do OneWay faz com que mais código seja gerado para conectar e lidar com a detecção de alterações. Você pode especificar explicitamente um modo para usar a associação OneWay ou TwoWay. Você também pode usar x:DefaultBindMode para alterar o modo padrão de {x:Bind} para um segmento específico da árvore de marcação. O modo especificado se aplica a qualquer expressão {x:Bind} nesse elemento e seus filhos, que não especificam explicitamente um modo como parte da associação.

Aplicativos de amostra que demonstram {x:Bind}

Uso do atributo XAML

<object property="{x:Bind}" .../>
-or-
<object property="{x:Bind propertyPath}" .../>
-or-
<object property="{x:Bind bindingProperties}" .../>
-or-
<object property="{x:Bind propertyPath, bindingProperties}" .../>
-or-
<object property="{x:Bind pathToFunction.functionName(functionParameter1, functionParameter2, ...), bindingProperties}" .../>
Termo Descrição
caminho da propriedade Uma cadeia de caracteres que especifica o caminho da propriedade para a associação. Mais informações estão na seção Caminho da propriedade abaixo.
bindingProperties
valor propName=[, valor propName=]* Uma ou mais propriedades de associação especificadas usando uma sintaxe de par nome/valor.
propName O nome da cadeia de caracteres da propriedade a ser definida no objeto de associação. Por exemplo, "Conversor".
value O valor para o qual definir a propriedade . A sintaxe do argumento depende da propriedade que está sendo definida. Aqui está um exemplo de uso de valor propName=em que o valor é uma extensão de marcação: Converter={StaticResource myConverterClass}. Para obter mais informações, consulte a seção Propriedades que você pode definir com {x:Bind} abaixo.

Exemplos

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

Este XAML de exemplo usa {x:Bind} com uma propriedade ListView.ItemTemplate . Observe a declaração de um valor x:DataType .

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

Caminho da propriedade

PropertyPath define o caminho para uma expressão {x:Bind} . Caminho é um caminho de propriedade que especifica o valor da propriedade, subpropriedade, campo ou método ao qual você está associando (a origem). Você pode mencionar o nome da propriedade Path explicitamente: {x:Bind Path=...}. Ou você pode omiti-lo: {x:Bind ...}.

Resolução do caminho da propriedade

{x:Vincular} não usa o DataContext como uma fonte padrão — em vez disso, ele usa a página ou o próprio controle de usuário. Portanto, ele procurará propriedades, campos e métodos no code-behind de sua página ou controle de usuário. Para expor seu modelo de exibição a {x:Bind}, você normalmente desejará adicionar novos campos ou propriedades ao code-behind para sua página ou controle de usuário. As etapas em um caminho de propriedade são delimitadas por pontos (.), e você pode incluir vários delimitadores para percorrer subpropriedades sucessivas. Use o delimitador de pontos, independentemente da linguagem de programação usada para implementar o objeto ao qual está sendo associado.

Por exemplo: em uma página, Text="{x:Bind Employee.FirstName}" procurará um membro Employee na página e, em seguida, um membro FirstName no objeto retornado por Employee. Se você estiver associando um controle de itens a uma propriedade que contém os dependentes de um funcionário, o caminho da propriedade poderá ser "Employee.Dependents" e o modelo de item do controle de itens se encarregará de exibir os itens em "Dependentes".

Para C++/CX, {x:Bind} não pode ser associado a campos e propriedades privados na página ou no modelo de dados – você precisará ter uma propriedade pública para que ele possa ser associado. A área de superfície para associação precisa ser exposta como classes/interfaces CX para que possamos obter os metadados relevantes. O atributo [Bindable] não deve ser necessário.

Com x:Bind, você não precisa usar ElementName=xxx como parte da expressão de associação. Em vez disso, você pode usar o nome do elemento como a primeira parte do caminho para a associação porque os elementos nomeados se tornam campos dentro da página ou do controle de usuário que representa a origem da associação raiz.

Coleções

Se a fonte de dados for uma coleção, um caminho de propriedade poderá especificar itens na coleção por sua posição ou índice. Por exemplo, "Teams[0]. Players", onde o literal "[]" inclui o "0" que solicita o primeiro item em uma coleção indexada a zero.

Para usar um indexador, o modelo precisa implementar IList<T> ou IVector<T> no tipo da propriedade que será indexada. (Observe que IReadOnlyList<T> e IVectorView<T> não dão suporte à sintaxe do indexador.) Se o tipo da propriedade indexada der suporte a INotifyCollectionChanged ou IObservableVector e a associação for OneWay ou TwoWay, ela se registrará e escutará notificações de alteração nessas interfaces. A lógica de detecção de alterações será atualizada com base em todas as alterações de coleção, mesmo que isso não afete o valor indexado específico. Isso ocorre porque a lógica de escuta é comum em todas as instâncias da coleção.

Se a fonte de dados for um Dicionário ou Mapa, um caminho de propriedade poderá especificar itens na coleção pelo nome da cadeia de caracteres. Por exemplo <, TextBlock Text="{x:Bind Players['John Smith']}" /> procurará um item no dicionário chamado "John Smith". O nome precisa ser colocado entre aspas e aspas simples ou duplas podem ser usadas. Hat (^) pode ser usado para escapar aspas em strings. Geralmente, é mais fácil usar aspas alternativas daquelas usadas para o atributo XAML. (Observe que IReadOnlyDictionary<T> e IMapView<T> não dão suporte à sintaxe do indexador.)

Para usar um indexador de cadeia de caracteres, o modelo precisa implementar a cadeia de caracteres IDictionary<, a cadeia de caracteres T> ou IMap<, T> no tipo da propriedade que será indexada. Se o tipo da propriedade indexada der suporte a IObservableMap e a associação for OneWay ou TwoWay, ela se registrará e escutará notificações de alteração nessas interfaces. A lógica de detecção de alterações será atualizada com base em todas as alterações de coleção, mesmo que isso não afete o valor indexado específico. Isso ocorre porque a lógica de escuta é comum em todas as instâncias da coleção.

Propriedades Anexadas

Para associar a propriedades anexadas, você precisa colocar a classe e o nome da propriedade entre parênteses após o ponto. Por exemplo, Text="{x:Bind Button22.( Grid.Row)}". Se a propriedade não for declarada em um namespace Xaml, você precisará prefixá-la com um namespace xml, que deve ser mapeado para um namespace de código no cabeçalho do documento.

Transmissão

As associações compiladas são fortemente tipadas e resolverão o tipo de cada etapa em um caminho. Se o tipo retornado não tiver o membro, ele falhará em tempo de compilação. Você pode especificar uma conversão para informar à associação o tipo real do objeto.

No caso a seguir, obj é uma propriedade do tipo object, mas contém uma caixa de texto, portanto, podemos usar Text="{x:Bind ((TextBox)obj). Texto}" ou Texto="{x:Bind obj.(TextBox.Text)}".

O campo groups3 em Text="{x:Bind ((data:SampleDataGroup)groups3[0]). Title}" é um dicionário de objetos, portanto, você deve convertê-lo em data:SampleDataGroup. Observe o uso do prefixo xml data: namespace para mapear o tipo de objeto para um namespace de código que não faz parte do namespace XAML padrão.

Observação: a sintaxe de conversão no estilo C# é mais flexível do que a sintaxe de propriedade anexada e é a sintaxe recomendada daqui para frente.

Lançamento sem caminho

O analisador de associação nativo não fornece uma palavra-chave para representar this como um parâmetro de função, mas dá suporte à conversão sem caminho (por exemplo, {x:Bind (x:String)}), que pode ser usada como um parâmetro de função. Portanto, {x:Bind MethodName((namespace:TypeOfThis))} é uma maneira válida de realizar o que é conceitualmente equivalente a {x:Bind MethodName(this)}.

Exemplo:

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

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

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

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

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

            this.InitializeComponent();
        }

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

Funções em caminhos de associação

Desde o Windows 10, versão 1607, {x: Bind} dá suporte ao uso de uma função como a etapa de folha do caminho de associação. Esse é um recurso poderoso para vinculação de dados que permite vários cenários na marcação. Consulte associações de função para obter detalhes.

Associação de eventos

A associação de eventos é um recurso exclusivo para associação compilada. Ele permite que você especifique o manipulador de um evento usando uma associação, em vez de ter que ser um método no code-behind. Por exemplo: Click="{x:Bind rootFrame.GoForward}".

Para eventos, o método de destino não deve ser sobrecarregado e também deve:

  • Combine a assinatura do evento.
  • OU não têm parâmetros.
  • OU têm o mesmo número de parâmetros de tipos que podem ser atribuídos a partir dos tipos dos parâmetros de evento.

No code-behind gerado, a associação compilada manipula o evento e o encaminha para o método no modelo, avaliando o caminho da expressão de associação quando o evento ocorre. Isso significa que, ao contrário das associações de propriedade, ele não rastreia as alterações no modelo.

Para obter mais informações sobre a sintaxe de cadeia de caracteres para um caminho de propriedade, consulte Sintaxe de caminho de propriedade, tendo em mente as diferenças descritas aqui para {x:Bind}.

Propriedades que você pode definir com {x:Bind}

{x:Vincular} é ilustrado com a sintaxe de espaço reservado bindingProperties porque há várias propriedades de leitura/gravação que podem ser definidas na extensão de marcação. As propriedades podem ser definidas em qualquer ordem com pares de valores propName=separados por vírgulas. Observe que você não pode incluir quebras de linha na expressão de associação. Algumas das propriedades exigem tipos que não têm uma conversão de tipo, portanto, exigem extensões de marcação próprias aninhadas no {x:Bind}.

Essas propriedades funcionam da mesma maneira que as propriedades da classe Binding.

Propriedade Descrição
Caminho Consulte a seção Caminho da propriedade acima.
Conversor Especifica o objeto conversor que é chamado pelo mecanismo de associação. O conversor pode ser definido em XAML, mas somente se você se referir a uma instância de objeto que você atribuiu em uma referência de extensão de marcação {StaticResource} a esse objeto no dicionário de recursos.
ConverterIdioma Especifica a cultura a ser usada pelo conversor. (Se você estiver configurando ConverterLanguage você também deve configurar o Converter.) A cultura é definida como um identificador baseado em padrões. Para obter mais informações, consulte ConverterLanguage.
Parâmetro do conversor Especifica o parâmetro do conversor que pode ser usado na lógica do conversor. (Se você estiver configurando ConverterParameter você também deve definir Converter.) A maioria dos conversores usa lógica simples que obtém todas as informações necessárias do valor passado para converter e não precisa de um valor ConverterParameter . O parâmetro ConverterParameter é para implementações de conversor moderadamente avançadas que têm mais de uma lógica que desativa o que é passado em ConverterParameter. Você pode escrever um conversor que usa valores diferentes de cadeias de caracteres, mas isso é incomum, consulte Comentários em ConverterParameter para obter mais informações.
Valor de fallback Especifica um valor a ser exibido quando a origem ou o caminho não puder ser resolvido.
Modo Especifica o modo de associação, como uma destas cadeias de caracteres: "OneTime", "OneWay" ou "TwoWay". O padrão é "OneTime". Observe que isso difere do padrão para {Binding}, que é "OneWay" na maioria dos casos.
Valor Alvo Especifica um valor a ser exibido quando o valor de origem for resolvido, mas for explicitamente nulo.
BindBack Especifica uma função a ser usada para a direção inversa de uma associação bidirecional.
UpdateSourceTrigger Especifica quando enviar as alterações de volta do controle para o modelo em associações TwoWay. O padrão para todas as propriedades, exceto TextBox.Text, é PropertyChanged; TextBox.Text é LostFocus.

Observação

Se você estiver convertendo a marcação de {Binding} para {x:Bind}, lembre-se das diferenças nos valores padrão da propriedade Mode . x:DefaultBindMode pode ser usado para alterar o modo padrão de x:Bind para um segmento específico da árvore de marcação. O modo selecionado aplicará todas as expressões x:Bind nesse elemento e seus filhos, que não especificam explicitamente um modo como parte da associação. O OneTime tem mais desempenho do que o OneWay, pois o uso do OneWay fará com que mais código seja gerado para conectar e lidar com a detecção de alterações.

Comentários

Como {x:Bind} usa código gerado para obter seus benefícios, ele requer informações de tipo em tempo de compilação. Isso significa que você não pode associar a propriedades em que não conhece o tipo com antecedência. Por isso, você não pode usar {x:Bind} com a propriedade DataContext , que é do tipo Object e também está sujeita a alterações em tempo de execução.

Ao usar {x:Bind} com modelos de dados, você deve indicar o tipo que está sendo associado definindo um valor x:DataType , conforme mostrado na seção Exemplos . Você também pode definir o tipo como uma interface ou tipo de classe base e, em seguida, usar conversões, se necessário, para formular uma expressão completa.

As associações compiladas dependem da geração de código. Portanto, se você usar {x:Bind} em um dicionário de recursos, o dicionário de recursos precisará ter uma classe code-behind. Consulte Dicionários de recursos com {x:Bind} para obter um exemplo de código.

Páginas e controles de usuário que incluem associações compiladas terão uma propriedade "Bindings" no código gerado. Entre elas estão os seguintes métodos:

  • Update() - Isso atualizará os valores de todas as associações compiladas. Qualquer associação unidirecional/bidirecional terá os ouvintes conectados para detectar alterações.
  • Initialize() - Se as ligações ainda não tiverem sido inicializadas, ele chamará Update() para inicializar as ligações
  • StopTracking() - Isso desconectará todos os ouvintes criados para associações unidirecionais e bidirecionais. Eles podem ser reinicializados usando o método Update().

Observação

A partir do Windows 10, versão 1607, a estrutura XAML fornece um conversor interno de booliano para visibilidade. O conversor mapeia true para o valor de enumeração Visible e false para Collapsed para que você possa vincular uma propriedade Visibility a um booliano sem criar um conversor. Observe que esse não é um recurso da associação de função, apenas da associação de propriedade. Para usar o conversor integrado, a versão do SDK de alvo mínimo do seu aplicativo deve ser 14393 ou posterior. Você não poderá usá-lo se seu aplicativo for voltado para versões anteriores do Windows 10. Para saber mais sobre as versões de destino, consulte Código adaptável de versão.

Dica Se você precisar especificar uma única chave para um valor, como em Path ou ConverterParameter, preceda-a com uma barra invertida: . \{ Como alternativa, coloque toda a cadeia de caracteres que contém as chaves que precisam ser escapadas em um conjunto de aspas secundário, por exemplo ConverterParameter='{Mix}'.

Converter, ConverterLanguage e ConverterLanguage estão todos relacionados ao cenário de conversão de um valor ou tipo da origem da associação em um tipo ou valor compatível com a propriedade de destino da associação. Para obter mais informações e exemplos, consulte a seção "Conversões de dados" de Associação de dados em detalhes.

{x:Vincular} é apenas uma extensão de marcação, sem nenhuma maneira de criar ou manipular essas associações programaticamente. Para obter mais informações sobre extensões de marcação, consulte Visão geral do XAML.