Compartilhar 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 associar dados. No entanto, você também pode declarar associaçõ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 Extensões de marcação e XAML WPF.

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

Declarar uma associação em XAML

Binding é uma extensão da marcação. Quando você usa a extensão de associação para declarar uma associação, a declaração consiste em uma série de cláusulas após a palavra-chave Binding separadas por vírgulas (,). As cláusulas na declaração da associação podem estar em qualquer ordem e há várias combinações possíveis. As cláusulas são pares Name=Value, em que Name é o nome da Binding propriedade e Value é o valor que você está definindo para a propriedade.

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

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

O exemplo anterior usa um tipo de objeto de dados simples de Person. O snippet 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 Binding maioria das propriedades da classe dessa maneira. Para obter mais informações sobre a extensão de associação e para obter uma lista de propriedades que não podem ser definidas usando a extensão de associação, consulte a Visão geral da Extensão de Binding Marcação de Associação (.NET Framework).

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

Sintaxe do elemento de objeto

A sintaxe de elemento de objeto é uma alternativa para criar a declaração de associaçã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 de objeto. No entanto, quando a extensão de marcação não dá suporte ao seu 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 de objeto.

A seção anterior demonstrou como associar com uma extensão XAML. O exemplo a seguir demonstra fazer a mesma associação, mas usa a sintaxe do elemento de 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 não dão suporte à sintaxe PriorityBinding de extensão XAML. É por isso que você deve usar a sintaxe do elemento de objeto se estiver declarando a MultiBinding ou a PriorityBinding em XAML.

Criar uma associação no código

Outra maneira de especificar uma associação é definir propriedades diretamente em um Binding objeto no código e, em seguida, atribuir a associação a uma propriedade. O exemplo a seguir mostra como criar um Binding objeto 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 associação:

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

Quando o objeto que você está vinculando é a FrameworkElement ou um FrameworkContentElement, você pode chamar o SetBinding método em seu objeto diretamente em vez de usar BindingOperations.SetBinding. Para obter um exemplo, consulte Como criar uma associação no código.

O exemplo anterior usa um tipo de objeto de dados simples de Person. Veja 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

Sintaxe do caminho de associação

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

  • No caso mais simples, o Path valor da propriedade é o nome da propriedade do objeto de origem a ser usado para a associaçã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 associação com a subpropriedade Order do objeto ou da propriedade ShoppingCart.

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

  • Os indexadores de uma propriedade podem ser especificados dentro de colchetes após o nome da propriedade na qual o indexador é aplicado. Por exemplo, a cláusula Path=ShoppingCart[0] define a associação ao índice que corresponde a como a indexação interna de sua propriedade lida com a cadeia de caracteres literal "0". Os indexadores aninhados também têm suporte.

  • Os indexadores e as subpropriedades podem ser combinados em uma cláusula Path. Por exemplo,Path=ShoppingCart.ShippingInfo[MailingAddress,Street].

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

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

  • Barras e nomes de propriedade podem ser combinados para percorrer as propriedades que são coleções. 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. O 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 escape

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

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

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

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

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

    • A barra invertida (\) é o caractere de escape.

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

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

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

Direção de associação

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

Modo de associação Descrição
BindingMode.TwoWay Atualiza a propriedade de destino ou a propriedade sempre que a propriedade de destino ou a propriedade de origem são alteradas.
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 de origem quando a propriedade de destino é alterada.
BindingMode.Default Faz com que o valor padrão Mode da propriedade de destino seja usado.

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 detectar alterações de origem (aplicáveis a associações OneWay e TwoWay), a origem deve implementar um mecanismo de notificação de alteração de propriedade adequado, como INotifyPropertyChanged. Para obter mais informações, consulte Fornecendo notificações de alteração.

Para TwoWay ou OneWayToSource associações, você pode controlar o tempo das atualizações de origem definindo a UpdateSourceTrigger propriedade. Para obter mais informações, consulte UpdateSourceTrigger.

Comportamentos padrão

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

  • É criado um conversor padrão que tenta fazer uma conversão de tipos entre o valor de origem de associação e o valor de destino de associação. Se a conversão não puder ser realizada, o conversor padrão retornará null.

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

  • Desde que a associação já tenha um contexto de dados (por exemplo, o contexto de dados herdado proveniente de um elemento pai) e qualquer item ou coleção que esteja sendo retornado por esse contexto seja apropriado para associação sem exigir mais modificações de caminho, uma declaração de associação não poderá ter nenhuma cláusula: {Binding}. Geralmente, é assim que uma associação é especificada para estilo de dados, em que a associação atua em uma coleção. Para obter mais informações, consulte Usando objetos inteiros como uma origem de associação.

  • O padrão Mode varia entre unidirecional e bidirecional, dependendo da propriedade de dependência que está sendo associada. Você sempre pode declarar o modo de associaçã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, são padronizadas para associações bidirecionais, mas a maioria das outras propriedades usa como padrão associações unidirecionais.

  • O valor padrão UpdateSourceTrigger também varia entre PropertyChanged e LostFocus dependendo da propriedade de dependência associada. 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.

Confira também