Visão geral de declarações vinculativas (WPF .NET)

Normalmente, os desenvolvedores declaram as ligaçõ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 associações no código. Este artigo descreve como declarar associações em XAML e em 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 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 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, onde Name é o Binding nome da 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 vincular a propriedade usando a TextBox.Text extensão de vinculação, especificando as Source propriedades e Path .

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

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

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 objeto. No entanto, quando a extensão de marcação não oferece suporte ao seu cenário, como quando o valor da propriedade é de um tipo que não é 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 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 PriorityBinding não oferecem suporte à sintaxe de extensão XAML. É por isso que você deve usar a sintaxe do elemento object se estiver declarando um ou um MultiBindingPriorityBinding 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 vinculaçã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 você está vinculando é um ou um FrameworkElementFrameworkContentElement, 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. 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 Path propriedade para especificar o valor de origem ao qual você deseja vincular:

  • No caso mais simples, o valor da propriedade é o Path 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 do 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 é um modo de 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 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 circunflexo ([ ]^) escapa do próximo caractere.

  • Se você definir Path em XAML, também precisará escapar (usando entidades XML) de 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 que são especiais para o analisador de extensão de marcação 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 propriedade para especificar a Binding.Mode direção da associação. Os seguintes modos são as opções disponíveis para atualizações de vinculação:

Modo de vinculaçã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 Mode propriedade:

<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 vinculação usará a Language propriedade do objeto de destino de vinculação. Em XAML, isso usa como padrão en-US ou herda o valor do elemento raiz (ou de qualquer elemento) da página, se um tiver sido definido explicitamente.

  • Contanto 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 retornada por esse contexto seja apropriada para vinculação sem exigir modificação de caminho adicional, uma declaração de vinculação não pode ter nenhuma cláusula: {Binding}. Essa geralmente é a maneira como uma associação é especificada para o estilo de dados, em que a associação atua sobre uma coleção. Para obter mais informações, consulte Usando objetos inteiros como uma fonte de vinculação.

  • O padrão Mode varia entre unidirecional e bidirecional, dependendo da propriedade de dependência que está sendo vinculada. 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 e RangeBase.Value, têm como padrão as vinculações bidirecionais, mas a maioria das outras propriedades tem como TextBox.Text padrão as associações unidirecionais.

  • O valor padrão UpdateSourceTrigger também varia entre PropertyChanged e LostFocus dependendo 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.

Confira também