Partilhar via


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

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 Vinculação de dados em profundidade.

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

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

Os objetos de ligação criados por {x:Bind} e {Binding} são amplamente equivalentes funcionalmente. Mas {x:Bind} executa código de finalidade especial, que gera em tempo de compilação, e {Binding} usa inspeção de objetos genérica em tempo de execução. Consequentemente, as ligações {x:Bind} (muitas vezes referidas como ligações compiladas) têm um ótimo desempenho, fornecem validação em tempo de compilação de suas expressões de vinculação e suportam depuração, permitindo que você defina pontos de interrupção nos arquivos de código que são gerados como a classe parcial para sua página. Esses arquivos podem ser encontrados em sua obj pasta, com nomes como (para C#) <view name>.g.cs.

Sugestão

{x:Bind} 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, já que o uso do OneWay faz com que mais código seja gerado para conectar e lidar com a deteçã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 para {x:Bind} para um segmento específico da árvore de marcação. O modo especificado aplica-se a quaisquer expressões {x:Bind} nesse elemento e seus filhos, que não especificam explicitamente um modo como parte da ligação.

Uso de atributos 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}" .../>
Term Description
propertyPath Uma cadeia de caracteres que especifica o caminho da propriedade para a vinculação. Mais informações estão na seção Caminho da propriedade abaixo.
bindingProperties
propNome=valor[, propNome=valor]* Uma ou mais propriedades de vinculação especificadas usando uma sintaxe de par nome/valor.
propNome O nome da cadeia de caracteres da propriedade a ser definida no objeto de vinculação. Por exemplo, "Converter".
value O valor a ser atribuído à propriedade. A sintaxe do argumento depende da propriedade que está sendo definida. Aqui está um exemplo de um propName= onde o valor é em si uma extensão de marcação: Converter={StaticResource myConverterClass}. Para obter mais informações, consulte Propriedades que você pode definir com a seção {x:Bind} abaixo.

Examples

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

Este exemplo de XAML 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 Path para uma expressão {x:Bind} . Path é um caminho de propriedade que especifica o valor da propriedade, subpropriedade, campo ou método ao qual você está vinculando (a fonte). 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:Bind} não usa o DataContext como uma fonte padrão — em vez disso, ele usa a própria página ou controle de usuário. Assim, ele procurará propriedades, campos e métodos no code-behind da 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. Os passos em um caminho de propriedade são delimitados por pontos (.), e pode-se incluir múltiplos delimitadores para percorrer subpropriedades sucessivas. Use o delimitador de pontos independentemente da linguagem de programação usada para implementar o objeto ao qual está vinculado.

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 vinculando um controle de itens a uma propriedade que contém dependentes de um funcionário, seu caminho de propriedade pode 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 vincular a campos e propriedades privados na página ou no modelo de dados – você precisará ter uma propriedade pública para que ela seja vinculável. A área de superfície para ligaçã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 ligaçã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 fonte de vinculação raiz.

Collections

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, "Equipas[0].Jogadores", onde o literal "[]" inclui o "0" que solicita o primeiro item de 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 suportam a sintaxe do indexador.) Se o tipo da propriedade indexada suportar INotifyCollectionChanged ou IObservableVector e a associação for OneWay ou TwoWay, ele registrará e ouvirá notificações de alteração nessas interfaces. A lógica de deteçã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 de aspas em strings. Geralmente, é mais fácil usar aspas alternativas daquelas usadas para o atributo XAML. (Note que IReadOnlyDictionary<T> e IMapView<T> não suportam a sintaxe do indexador.)

Para usar um indexador de cadeia de caracteres, o modelo precisa implementar IDictionary<string, T> ou IMap<string, T> no tipo da propriedade que será indexada. Se o tipo da propriedade indexada suportar IObservableMap e a associação for OneWay ou TwoWay, ele registrará e ouvirá notificações de alteração nessas interfaces. A lógica de deteçã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 vincular às 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 deverá ser mapeado para um namespace de código no cabeçalho do documento.

Fundiçã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 um tipo para indicar à ligação o tipo real do objeto.

No caso a seguir, obj é uma propriedade do objeto type, mas contém uma caixa de texto, para que possamos usar Text="{x:Bind ((TextBox)obj). Text}" ou Text="{x:Bind obj.(TextBox.Text)}".

O campo groups3 em Text="{x:Bind ((data:SampleDataGroup)groups3[0]). Title}" é um dicionário de objetos, então 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.

Nota: A sintaxe de conversão no estilo C# é mais flexível do que a sintaxe de propriedade anexada e é a sintaxe recomendada no futuro.

Fundição sem percurso definido

O analisador de ligação nativo não fornece uma palavra-chave para representar this como um parâmetro de função, mas suporta 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 ligação

A partir do Windows 10, versão 1607, {x:Bind} suporta o uso de uma função como o passo final do caminho de associação de dados. Este é um recurso poderoso para vinculação de dados que permite vários cenários na marcação. Consulte Ligações de função para obter detalhes.

Vinculação de eventos

A vinculação de eventos é um recurso exclusivo para a vinculação compilada. Ele permite que você especifique o manipulador para um evento usando uma ligaçã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:

  • Verifique a assinatura do evento.
  • OU não têm parâmetros.
  • OU têm o mesmo número de parâmetros de tipos que são atribuíveis a partir dos tipos de 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 vinculação quando o evento ocorre. Isso significa que, ao contrário das associações de propriedade, ele não acompanha às 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:Bind} é 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 devalores= separados por vírgula. Observe que não é possível incluir quebras de linha na expressão de vinculação. Algumas das propriedades exigem tipos que não têm uma conversão de tipo, portanto, elas exigem extensões de marcação próprias aninhadas dentro do {x:Bind}.

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

Propriedade Description
Path Consulte a seção Caminho da propriedade acima.
Conversor Especifica o objeto conversor que é chamado pelo mecanismo de vinculação. O conversor pode ser definido em XAML, mas somente se você fizer referência a uma instância de objeto atribuída em uma referência de extensão de marcação {StaticResource} a esse objeto no dicionário de recursos.
ConversorLanguage Especifica a cultura a ser usada pelo conversor. (Se você estiver definindo ConverterLanguage você também deve estar definindo Converter.) A cultura é definida como um identificador baseado em padrões. Para obter mais informações, consulte ConverterLanguage.
ConverterParameter Especifica o parâmetro do conversor que pode ser usado na lógica do conversor. (Se você estiver definindo ConverterParameter , você também deve definir Converter.) A maioria dos conversores usa lógica simples que obtém todas as informações de que precisam 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 desliga 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.
FallbackValue Especifica um valor a ser exibido quando a origem ou o caminho não puderem ser resolvidos.
Modo Especifica o modo de ligaçã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.
TargetNullValue Especifica um valor a ser exibido quando o valor de origem é resolvido, mas é explicitamente nulo.
BindBack Especifica uma função a ser usada para a direção inversa de uma ligação bidirecional.
UpdateSourceTrigger Especifica quando enviar as alterações do controle para o modelo em associações bidirecionais. O padrão para todas as propriedades, exceto TextBox.Text é PropertyChanged; TextBox.Text é LostFocus.

Observação

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

Observações

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 vincular a propriedades onde você não sabe 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 ao qual está sendo vinculado 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 casts, se necessário, para formular uma expressão completa.

As ligaçõ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 ligações compiladas terão uma propriedade "Bindings" no código gerado. Isso inclui os seguintes métodos:

  • Update() - Isso atualizará os valores de todas as associações compiladas. Qualquer ligação unidirecional/bidirecional terá os ouvintes conectados para detetar alterações.
  • Initialize() - Se as associações ainda não tiverem sido inicializadas, ele chamará Update() para inicializar as ligações
  • StopTracking() - Isso desconectará todos os ouvintes criados para ligaçõ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 Boolean to Visibility integrado. 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 Boolean sem criar um conversor. Observe que esse não é um recurso de vinculação de função, apenas vinculação de propriedade. Para usar o conversor interno, a versão mínima do SDK de destino do seu aplicativo deve ser 14393 ou posterior. Você não pode usá-lo quando seu aplicativo tem como alvo versões anteriores do Windows 10. Para obter mais informações sobre versões de destino, consulte Código adaptável de versão.

Sugestão

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 relacionados ao cenário de conversão de um valor ou tipo da fonte de vinculação em um tipo ou valor compatível com a propriedade de destino de vinculação. Para obter mais informações e exemplos, consulte a seção "Conversões de dados" de Vinculação de dados em profundidade.

{x:Bind} é apenas uma extensão de marcação, sem nenhuma maneira de criar ou manipular tais ligações programaticamente. Para saber mais sobre extensões de marcação, veja Visão geral de XAML.