Partilhar via


O que são declarações vinculativas? (WPF .NET)

Normalmente, os desenvolvedores declaram as associações diretamente na marcação XAML dos elementos da interface do usuário aos quais desejam vincular dados. No entanto, você também pode declarar ligações no código. Este artigo descreve como declarar associações em XAML e no código.

Pré-requisitos

Antes de ler este artigo, é importante que você esteja familiarizado com o conceito e o uso de extensões de marcação. Para obter mais informações sobre extensões de marcação, consulte Markup Extensions e WPF XAML.

Este artigo não aborda conceitos de vinculação de dados. Para obter uma discussão sobre conceitos de vinculação de dados, consulte Visão geral da vinculação de dados.

Declarar uma associação em XAML

Binding é uma extensão de marcação. Quando você usa a extensão binding para declarar uma vinculação, a declaração consiste em uma série de cláusulas seguindo a palavra-chave Binding e separadas por vírgulas (,). As cláusulas da declaração vinculativa podem estar em qualquer ordem e há muitas combinações possíveis. As cláusulas são pares de Nome=Valor, onde Nome é o nome da propriedade Binding e Valor é o valor que estás a definir para a propriedade.

Ao criar cadeias de caracteres de declaração de vinculação na marcação, elas devem ser anexadas à propriedade de dependência específica de um objeto de destino. O exemplo a seguir mostra como vincular a propriedade TextBox.Text usando a extensão de ligação, especificando as propriedades Source e Path.

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>

O exemplo anterior usa um tipo de objeto de dados simples de Person. O trecho a seguir é o código desse objeto:

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

Você pode especificar a maioria das propriedades da classe Binding dessa maneira. Para obter mais informações sobre a extensão de vinculação e para obter uma lista de propriedades de Binding que não podem ser definidas usando a extensão de vinculação, consulte a Binding Markup Extension (.NET Framework) visão geral.

Para obter um exemplo sobre como criar uma associação em XAML, consulte Como criar uma associação de dados.

Sintaxe do elemento objeto

A sintaxe do elemento objeto é uma alternativa à criação da declaração de vinculação. Na maioria dos casos, não há nenhuma vantagem específica em usar a extensão de marcação ou a sintaxe do elemento objeto. No entanto, quando a extensão de marcação não oferece suporte ao cenário, como quando o valor da propriedade é de um tipo que não é de cadeia de caracteres para o qual não existe conversão de tipo, você precisa usar a sintaxe do elemento objeto.

A seção anterior demonstrou como vincular com uma extensão XAML. O exemplo a seguir demonstra fazer a mesma ligação, mas usa a sintaxe do elemento objeto:

<TextBlock>
    <TextBlock.Text>
        <Binding Source="{StaticResource myDataSource}" Path="Name"/>
    </TextBlock.Text>
</TextBlock>

Para obter mais informações sobre os diferentes termos, consulte Sintaxe XAML em Detalhes (.NET Framework).

MultiBinding e PriorityBinding

MultiBinding e PriorityBinding não suportam a sintaxe da extensão XAML. É por isso que você deve usar a sintaxe do elemento object se estiver declarando um MultiBinding ou um PriorityBinding em XAML.

Criar uma ligação no código

Outra maneira de especificar uma associação é definir propriedades diretamente em um objeto Binding no código e, em seguida, atribuir a associação a uma propriedade. O exemplo a seguir mostra como criar um objeto Binding no código.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Make a new data source object
    var personDetails = new Person()
    {
        Name = "John",
        Birthdate = DateTime.Parse("2001-02-03")
    };

    // New binding object using the path of 'Name' for whatever source object is used
    var nameBindingObject = new Binding("Name");

    // Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay;
    nameBindingObject.Source = personDetails;
    nameBindingObject.Converter = NameConverter.Instance;
    nameBindingObject.ConverterCulture = new CultureInfo("en-US");

    // Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)

    ' Make a new data source object
    Dim personDetails As New Person() With {
        .Name = "John",
        .Birthdate = Date.Parse("2001-02-03")
    }

    ' New binding object using the path of 'Name' for whatever source object is used
    Dim nameBindingObject As New Binding("Name")

    ' Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay
    nameBindingObject.Source = personDetails
    nameBindingObject.Converter = NameConverter.Instance
    nameBindingObject.ConverterCulture = New CultureInfo("en-US")

    ' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)

End Sub

O código anterior definiu o seguinte na ligação:

  • O caminho de uma propriedade no objeto da fonte de dados.
  • O modo da ligação.
  • A fonte de dados, neste caso, uma instância de objeto simples que representa uma pessoa.
  • Um conversor opcional que processa o valor vindo do objeto de fonte de dados antes de ser atribuído à propriedade de destino.

Quando o objeto que se está a associar é um FrameworkElement ou um FrameworkContentElement, pode-se chamar o método SetBinding no seu objeto diretamente em vez de usar o BindingOperations.SetBinding. Para obter um exemplo, consulte Como: Criar uma Vinculação em Código.

O exemplo anterior usa um tipo de objeto de dados simples de Person. A seguir está o código para esse objeto:

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

Sintaxe do caminho de vinculação

Use a propriedade Path para especificar o valor de origem ao qual você deseja vincular:

  • No caso mais simples, o valor da propriedade Path é o nome da propriedade do objeto de origem a ser usado para a ligação, como Path=PropertyName.

  • As subpropriedades de uma propriedade podem ser especificadas por uma sintaxe semelhante à do C#. Por exemplo, a cláusula Path=ShoppingCart.Order define a ligação à subpropriedade Order do objeto ou propriedade ShoppingCart.

  • Para vincular a uma propriedade anexada, coloque parênteses ao redor da propriedade anexada. Por exemplo, para vincular à propriedade anexada DockPanel.Dock, a sintaxe é Path=(DockPanel.Dock).

  • Os indexadores de uma propriedade podem ser especificados entre colchetes após o nome da propriedade onde o indexador é aplicado. Por exemplo, a cláusula Path=ShoppingCart[0] define a ligação ao índice que corresponde à forma como a indexação interna da sua propriedade lida com a cadeia de caracteres literal "0". Indexadores aninhados também são suportados.

  • Indexadores e subpropriedades podem ser misturados em uma cláusula Path; Por exemplo, Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

  • Dentro dos indexadores. Você pode ter vários parâmetros do indexador separados por vírgulas (,). O tipo de cada parâmetro pode ser especificado entre parênteses. Por exemplo, você pode ter Path="[(sys:Int32)42,(sys:Int32)24]", onde sys é mapeado para o namespace System.

  • Quando a origem é uma vista de coleção, o item atual pode ser especificado com uma barra (/). Por exemplo, a cláusula Path=/ define a vinculação ao item atual no modo de exibição. Quando a origem é uma coleção, essa sintaxe especifica o item atual do modo de exibição de coleção padrão.

  • Nomes de propriedade e barras podem ser combinados para navegar por propriedades que são coleções de itens. Por exemplo, Path=/Offices/ManagerName especifica o item atual da coleção de origem, que contém uma propriedade Offices que também é uma coleção. Seu item atual é um objeto que contém uma propriedade ManagerName.

  • Opcionalmente, um caminho de ponto (.) pode ser usado para vincular à fonte atual. Por exemplo, Text="{Binding}" é equivalente a Text="{Binding Path=.}".

Mecanismo de fuga

  • Dentro dos indexadores ([ ]), o caractere de acento circunflexo (^) escapa do caractere seguinte.

  • Se você definir Path em XAML, também precisará escapar (usando entidades XML) de certos caracteres que são especiais para a definição de linguagem XML:

    • Use &amp; para escapar do personagem "&".

    • Use &gt; para escapar da tag final ">".

  • Além disso, se você descrever toda a associação em um atributo usando a sintaxe da extensão de marcação, precisará escapar (usando barra invertida \) caracteres que são especiais para o analisador de extensão de marcação WPF:

    • Backslash (\) é o próprio personagem de fuga.

    • O sinal de igual (=) separa o nome da propriedade do valor da propriedade.

    • A vírgula (,) separa as propriedades.

    • A cinta direita (}) é o final de uma extensão de marcação.

Direção de ligação

Use a propriedade Binding.Mode para especificar a direção da ligação. Os seguintes modos são as opções disponíveis para atualizações de vinculação:

Modo de ligação Descrição
BindingMode.TwoWay Atualiza a propriedade de destino ou a de origem sempre que uma delas é alterada.
BindingMode.OneWay Atualiza a propriedade de destino somente quando a propriedade de origem é alterada.
BindingMode.OneTime Atualiza a propriedade de destino somente quando o aplicativo é iniciado ou quando o DataContext sofre uma alteração.
BindingMode.OneWayToSource Atualiza a propriedade fonte quando a propriedade de destino é alterada.
BindingMode.Default Faz com que seja usado o valor padrão Mode da propriedade de destino.

Para obter mais informações, consulte a enumeração BindingMode.

O exemplo a seguir mostra como definir a propriedade Mode:

<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />

Para detetar alterações na fonte (aplicáveis a ligações de OneWay e TwoWay), a fonte deve implementar um mecanismo adequado de notificação de alteração de propriedade, como INotifyPropertyChanged. Para obter mais informações, consulte Disponibilização de notificações de alterações.

Para vínculos TwoWay ou OneWayToSource, pode-se controlar o timing das atualizações de origem definindo a propriedade UpdateSourceTrigger. Para obter mais informações, consulte UpdateSourceTrigger.

Comportamentos padrão

O comportamento padrão é o seguinte, se não especificado na declaração:

  • É criado um conversor padrão que tenta fazer uma conversão de tipo entre o valor de origem da vinculação e o valor de destino da ligação. Se uma conversão não puder ser feita, o conversor padrão retornará null.

  • Se você não definir ConverterCulture, o mecanismo de vinculação usará a propriedade Language do objeto de destino de vinculação. Em XAML, o padrão é en-US ou herda o valor do elemento raiz (ou qualquer elemento) da página, se um tiver sido definido explicitamente.

  • Desde que a ligação já tenha um contexto de dados (por exemplo, o contexto de dados herdado de um elemento pai) e qualquer item ou coleção retornada por esse contexto seja apropriado para a ligação sem necessidade de modificações adicionais do caminho, uma declaração de ligação pode não ter cláusulas: {Binding}. Muitas vezes, esta é a forma como uma vinculação é especificada para o estilo de dados, onde a vinculação atua sobre uma coleção. Para obter mais informações, consulte Usando objetos inteiros como uma fonte de vinculação.

  • O Mode padrão varia entre unidirecional e bidirecional, dependendo da propriedade de dependência que está sendo vinculada. Você sempre pode declarar o modo de vinculação explicitamente para garantir que sua associação tenha o comportamento desejado. Em geral, as propriedades de controle editáveis pelo usuário, como TextBox.Text e RangeBase.Value, usam como padrão ligações bidirecionais, mas a maioria das outras propriedades usa como padrão ligações unidirecionais.

  • O valor UpdateSourceTrigger padrão varia entre PropertyChanged e LostFocus dependendo também da propriedade de dependência vinculada. O valor padrão para a maioria das propriedades de dependência é PropertyChanged, enquanto a propriedade TextBox.Text tem um valor padrão de LostFocus.

Ver também