Revisão de Associação de Dados

Windows Presentation Foundation (WPF) associação de dados fornece uma simples e consistente maneira para aplicações apresentar e interagir com dados. Elementos podem ser vinculados a dados de uma variedade de fontes de dados na forma de objetos common language runtime (CLR) e XML. ContentControlsistema autônomo sistema autônomo Button e ItemsControlsistema autônomo sistema autônomo ListBox e ListView tem funcionalidade interna para ativar o estilo flexível de itens de dados único ou coleções de itens de dados. Ordenar, filtrar, e visualização de grupos podem ser geradas sobre os dados.

A funcionalidade de associação de dados WPF possui várias vantagens sobre modelos tradicionais, incluindo uma ampla gama de propriedades que herdam suporte a associação de dados, representação de dados UI flexível, e uma separação limpa da lógica de negócios da UI.

Este tópico primeiramente discute conceitos fundamentais para a associação de dados WPF e então vai afundo no uso da classe Binding e outras funcionalidades da associação de dados.

Este tópico contém as seguintes seções.

  • O que é Associação de Dados?
  • Conceitos Básicos de Associação de Dados
  • Criando uma Associação
  • Conversão de Dados
  • Associando a Coleções
  • Padronização de Dados
  • Validação de Dados
  • Mecanismo de Depuração
  • Tópicos relacionados

O que é Associação de Dados?

Associação de Dados é o processo que estabelece uma conexão entre a aplicação UI e a lógica de negócios. Se a associação possui configurações corretas e os dados fornecem notificações adequadas, então, quando os dados mudam de valor, os elementos que são associados aos dados refletem as mudanças automaticamente. Associação de dados também pode significar que uma representação externa de dados em uma modificação de elemento, então os dados subjacentes podem ser automaticamente atualizados para refletir a mudança. Por exemplo, se o usuário edita o valor em um elemento TextBox, os valores dos dados subjacentes são automaticamente atualizados para refletir aquela mudança.

Um uso típico de associação de dados é colocar dados de configuração de servidor ou local em formulários ou outros controles UI. Em WPF, este conceito é expandido para incluir a associação de um amplo espectro de propriedades para uma variedade de fontes de dados. Em WPF, propriedades de dependência de elementos podem ser associados a objetos CLR (incluindo objetos ADO.NET ou objetos associados com Serviços Web e propriedades Web) e dados XML.

Para um exemplo de associação de dados, dê uma olhada na seguinte aplicação UI de Demonstração de ligação de dados:

Captura de tela de exemplo de associação de dados

Este último é o UI de uma aplicação que mostra uma lista de itens de leilão. Esta aplicação demonstra as seguintes funcionalidades de associação de dados:

  • O conteúdo do ListBox é associado a uma coleção de objetos AuctionItem. Um objeto AuctionItem tem propriedades tais como Description, StartPrice, StartDate, Category, SpecialFeatures, etc.

  • Os dados (objetos AuctionItem) mostrados no ListBox é padronizado de forma que a descrição e o preço atual são mostrados para cada item. Isto é feito utilizando um DataTemplate. Adicionalmente, a aparência de cada item depende do valor SpecialFeaturesdo AuctionItem sendo exibido. Se o valor SpecialFeatures do AuctionItem é Color, o item tem uma borda azul. Se o valor é Highlight, o item tem uma borda laranja e uma estrela. A seção Padronização de Dados fornece informação sobre padronização de dados.

  • O usuário pode agrupar, filtrar ou ordenar os dados utilizando os CheckBoxs fornecidos. Na imagem acima, os CheckBox "Agrupar por categoria" e "Ordenar por categoria e data" são selecionados. Você deve ter percebido que os dados são agrupados baseados na categoria do produto, e no nome da categoria em ordem alfabética. É difícil perceber da imagem, mas os itens também estão ordenados pela data de início dentro de cada categoria. Isto é feito utilizando uma visualização de coleção. A seção Associando Coleções discute visualizações de coleções.

  • Quando o usuário seleciona um item, o ContentControl exibe os detalhes do item selecionado. Isto é chamado de Master-Detail scenario. A seção Cenário de Detalhe-Mestre fornece informação sobre os tipos de associação de cenário.

  • O tipo da propriedade StartDate é DateTime, que retorna a data que inclui o tempo em milissegundos. Nesta aplicação, um conversor personalizado foi utilizado para que string de data menores fosse exibida. A seção Conversão de Dados fornece informações sobre conversores.

Quando o usuário clica o botão Add Product , o seguinte formulário aparece:

Página Add Product Listing

Quando o usuário edita os campos no formulário, visualiza a listagem de produto usando os painéis de visualização rápida e visualização mais detalhada, e então clica em submit para adicionar o novo produto na listagem. Qualquer funcionalidade de agrupamento, filtro e ordenação existentes serão aplicadas para a nova entrada. Neste caso particular, o item inserido na imagem a acima será exibido como o segundo item dentro da categoria Computer.

Não é mostrado nessa imagem a validação lógica fornecida em Start Date TextBox. Se o usuário entra com uma data inválida (formato inválido ou data anterior), o usuário será notificado com um ToolTip e um ponto de exclamação vermelha próximo ao TextBox. A seção Validação de Dados discute como criar validação lógica.

Antes de continuar com as diferentes funcionalidades de associação de dados delineados anteriormente, discutiremos na próxima seção os conceitos fundamentais que são críticos para o entendimento de associação de dados WPF.

Conceitos Básicos de Associação de Dados

Esta seção contém as seguintes subseções.

  • Direção do Fluxo de Dados
  • O Que Causa Atualização de Fonte

Independente de qual elemento você está associando e a natureza de sua fonte de dados, cada associação segue o modelo ilustrado na seguinte figura:

Diagrama de associação de dados básica

Como ilustrado na figura anterior, associação de dados é essencialmente a ponte entre seu alvo da associação e sua fonte da associação. A figura demonstra os seguintes conceitos fundamentais de associação de dados WPF:

  • Normalmente, cada ligação tem esses quatro componentes: a destino de vinculação objeto, uma propriedade de destino, um fonte da ligaçãoe um caminho para o valor de fonte da ligação para usar. Por exemplo, se você quer associar o conteúdo de um TextBox à propriedade Nome de objeto Empregado , seu objeto alvo é o TextBox, e a propriedade alvo é a propriedade Text , o valor a ser usado é o Nome, e o objeto fonte é o objeto Employee.

  • A propriedade alvo deve ser uma propriedade de dependência. A maioria das propriedades UIElement são propriedade de dependência e a maioria das propriedade de dependência, exceto as somente leitura, aceitam associação de dados por padrão. (Somente tipos DependencyObject podem definir propriedade de dependência e todos UIElements derivam de DependencyObject.)

  • Embora não especificado na figura, é preciso observar que o fonte da ligação objeto não está restrito a sendo um personalizado CLR objeto. WPF vinculação de dados oferece suporte a dados na forma de CLR objetos e XML. Para dar alguns exemplos, sua fonte da associação pode ser um UIElement, qualquer lista de objetos, um objeto CLR que é associado a dados com ADO.NET ou Serviços Web, ou um NóXml que contém seus dados XML. Para obter mais informações, consulte Visão geral sobre associação de fontes.

Enquanto você lê pelos tópicos software development kit (SDK) , é importante lembrar que quando você está estabelecendo uma associação, você está associando um alvo da associação a uma fonte da associação. Por exemplo, se você está exibindo alguns dados XML subjacentes em uma ListBox você está usando associação de dados, você está associando seu ListBox aos dados XML.

Para estabelecer uma associação, você usa o objeto Binding. O resto deste tópico discute muitos dos conceitos associados e algumas das propriedades e usos do objeto Binding.

Direção do Fluxo de Dados

Como mencionado anteriormente e indicado pela seta na figura acima, o fluxo de dados de uma associação pode ir do alvo da associação para a fonte da associação (por exemplo, o valor da fonte modifica quando o usuário edita o valor de um TextBox) e/ou da fonte da associação para o alvo da associação (por exemplo, o conteúdo de sua TextBox é atualizado com a mudança na fonte da associação) se a fonte da associação fornece as notificações adequadas.

Você pode querer que sua aplicação permita usuários modificar os dados e propagá-los de volta para o objeto fonte. Ou você não quer permitir que usuários atualizem a fonte de dados. Você pode controlar isto ao definir a propriedade Mode do seu objeto Binding. A seguinte figura ilustra os diferentes tipos de fluxo de dados:

Fluxo de dados de associação de dados

  • Associação OneWay faz com que as mudanças na propriedade fonte sejam automaticamente atualizadas na propriedade alvo, porém mudanças na propriedade alvo não são propagadas de volta para a propriedade fonte. Este tipo de associação é adequado se o controle sendo associado é implicitamente somente leitura. Por exemplo, você pode associar uma fonte como um mostrador de cotação de ações ou talvez sua propriedade alvo não tenha nenhuma interface de controle disponível para realizar mudanças, tais como uma cor de fundo de uma tabela. Não há necessidade de monitorar as mudanças da propriedade alvo, usando o modo de associação OneWay evita o overhead do modo de associação TwoWay.

  • A associação TwoWay faz com que mudanças em tanto a propriedade fonte quanto a propriedade alvo sejam automaticamente atualizadas na outra. Este tipo de associação é apropriado para formulários editáveis ou outros cenários UI totalmente interativos. O padrão da maioria das propriedades é associação OneWay, mas algumas propriedades de dependência (tipicamente propriedades de controles editáveis pelo usuário tais como a propriedade Text do TextBox e a propriedade IsCheckeddo CheckBox) tem como padrão a associação TwoWay. Uma maneira de determinar programaticamente se uma propriedade de dependência é associada em direção única ou bidirecionalmente por padrão é definir o meta-dado da propriedade usando GetMetadata e especificando o valor booleano da propriedade BindsTwoWayByDefault.

  • OneWayToSource é o inverso da associação OneWay; só atualiza a propriedade fonte quando a propriedade alvo é modificada. Um cenário exemplo é se você só precisa reavaliar o valor da fonte de um UI.

  • Não é ilustrado na figura a associação OneTime, que faz com que a propriedade fonte inicialize a propriedade alvo, mas mudanças subsequentes não são propagadas. Isto significa que se o contexto de dados sofre uma mudança ou o objeto no contexto de dados é modificado, então a mudança é refletida na propriedade alvo. Este tipo de associação é apropriado se você está usando dados onde tanto um estado atual momentâneo é apropriado para o usuário ou os dados são realmente estáticos. Este tipo de associação também é útil se você quer inicializar sua propriedade alvo com alguns valores da propriedade fonte e o contexto de dados não é conhecido de antemão. Isto é essencialmente uma forma mais simples da associação OneWay que fornece uma performance melhor em casos onde o valor da fonte não é modificado.

Note que para detectar mudanças (aplicáveis a associações OneWay e TwoWay), a fonte deve implementar uma propriedade de mecanismo de notificação de mudança adequado tal como o INotifyPropertyChanged. Consulte Como: Implement Property Change Notification para um exemplo de uma implementação INotifyPropertyChanged.

A página da propriedade Mode fornece mais informações sobre modos de associação de dados e um exemplo de como especificar a direção da associação.

O Que Causa Atualização de Fonte

Associações que são TwoWay ou OneWayToSource escutam por mudanças na propriedade alvo e propaga-las de volta para a fonte. Isto é conhecido como atualização da fonte. Por exemplo, você pode editar o texto de uma CaixaDeTexto para modificar o valor da fonte subjacente. Como descrito na seção anterior, a direção do fluxo de dados é determinado pelo valor da propriedade Mode da associação.

Entretanto, o valor da fonte é atualizado enquanto você está editando o texto ou depois de você terminar o texto e você aponta seu mouse fora da CaixaTexto? A propriedade UpdateSourceTrigger da associação determina qual gatilho atualiza a fonte. Os pontos nas setas para direita na seguinte figura ilustra o papel da propriedadeUpdateSourceTrigger:

Diagrama de UpdateSourceTrigger

Se o valor UpdateSourceTrigger é PropertyChanged, então o valor apontado pela seta para direita do TwoWay ou as associações OneWayToSource são atualizadas assim que a propriedade alvo é modificada. Entretanto, se o valor UpdateSourceTrigger é LostFocus, então o valor somente é atualizado com o novo valor quando o alvo perde o foco.

Similar a propriedade Mode, diferentes propriedades de dependência possuem valores padrão diferentes UpdateSourceTrigger. O valor da maioria das propriedades de dependência é PropertyChanged, enquanto a propriedade Text tem o valor padrão de LostFocus. Isto significa que a fonte é usualmente atualizada sempre que a propriedade alvo é modificada, o que é bom para CheckBox e outros controles simples. Entretanto, para textos campos, atualizar depois de cada teclada pode diminuir a performance e impedir o usuário da oportunidade de voltar e corrigir erros de digitação antes de enviar os novos valores. É por isso que a propriedade Text tem valor padrão LostFocus ao invés de PropertyChanged.

Veja a página da propriedade UpdateSourceTrigger para informação sobre como encontrar o valor padrão de UpdateSourceTrigger de uma propriedade de dependência.

A seguinte tabela fornece um cenário exemplo para cada valor UpdateSourceTrigger usando o TextBox como um exemplo:

Valor de UpdateSourceTrigger

Quando o Valor da Fonte é Atualizado

Cenário Exemplo para CaixaTexto

LostFocus (padrão de TextBox.Text)

Quando o controle CaixaTexto perde foco

Uma TextBox que é associada com validação lógica (veja a seção Validação de Dados)

PropriedadeModificada

Enquanto você digita dentro da TextBox

Controles TextBox em uma janela de sala de bate papo

Explicit

Quando uma aplicação chama UpdateSource

Controles TextBox em formulários editáveis (atualiza o valor da fonte somente quando o usuário clica no botão enviar)

Para um exemplo, consulte Como: Control When the TextBox Text Updates the Source.

Criando uma Associação

Esta seção contém as seguintes subseções.

  • Especificando a Fonte da Associação
  • Especificando o Caminho ao Valor
  • Associação e Expressão de Associação

Para recapitulate alguns dos conceitos descritos nas seções anteriores, você estabelecer uma ligação usando o Binding objeto e cada ligação geralmente tem quatro componentes: destino de vinculação, a propriedade de destino, fonte da vinculação e um caminho para o valor de fonte a ser usado. Esta seção discute como estabelecer uma associação.

Considere o seguinte exemplo, em que o objeto fonte da associação é uma classe com nome MeusDados que é definido no namespace ExemploSDK . Para propósito de demonstração, a classe MeusDados tem uma propriedade string com nome NomeDaCor, cujo valor está definido como "Vermelho". Então, este exemplo gera um botão com um fundo vermelho.

<DockPanel
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:c="clr-namespace:SDKSample">
  <DockPanel.Resources>
    <c:MyData x:Key="myDataSource"/>
  </DockPanel.Resources>
  <DockPanel.DataContext>
    <Binding Source="{StaticResource myDataSource}"/>
  </DockPanel.DataContext>
  <Button Background="{Binding Path=ColorName}"
          Width="150" Height="30">I am bound to be RED!</Button>
</DockPanel>

Para mais detalhes sobre a sintaxe de declaração de associações e para exemplos de como definir uma associação no código, consulte Resumo de Declaração de Associações.

Se aplicarmos este exemplo ao nosso diagrama básico, a figura resultante parece com o seguinte. Isto é uma associação OneWay porque a propriedade Background suporta associação OneWay por padrão.

Diagrama de associação de dados

Você deve imaginar porquê isto funciona mesmo se a propriedade NomeDaCor é do tipo string enquanto que a propriedade Background é do tipo Brush. Este tipo padrão de conversão em funcionamento é discutido na seção Conversão de Dados.

Especificando a Fonte da Associação

Perceba que no exemplo anterior, a fonte da associação é especificado definindo a propriedade DataContext no elemento DockPanel. O Button então herda o valor DataContext do DockPanel, que é o elemento pai. Para reiterar, o objeto fonte da associação é um dos quatro componentes necessários de uma associação. Portanto, sem o objeto fonte sendo especificando, a associação não fará nada.

Existem várias maneiras de especificar o objeto fonte da associação. Usar a propriedade DataContext no elemento pai é útil quando você está associando propriedades de elementos múltiplos à mesma fonte. Entretanto, as vezes pode ser mais apropriado especificar a fonte da associação em declarações individuais de associação. No exemplo anterior, ao invés de usar a propriedade DataContext, você pode especificar a fonte da associação definindo a propriedade Source diretamente na declaração da associação do botão, como no seguinte exemplo:

<DockPanel.Resources>
  <c:MyData x:Key="myDataSource"/>
</DockPanel.Resources>
<Button Width="150" Height="30"
        Background="{Binding Source={StaticResource myDataSource},
                             Path=ColorName}">I am bound to be RED!</Button>

Ao invés de definir a propriedade DataContext em um elemento diretamente, herdando o valor DataContext de um ancestral (como o botão no primeiro exemplo), e explicitamente especificando a fonte da associação ao definir a propriedade Source no Binding (como o botão no último exemplo), você também pode usar a propriedade ElementName da propriedade RelativeSource para especificar a fonte da associação. A propriedade ElementName é útil quando você está associando a outros elementos em sua aplicação, como quando você está usando uma barra deslisante para ajustar a largura de um botão. A propriedade RelativeSourceé útil quando a associação é especificada em um ControlTemplate ou um Style. Para obter mais informações, consulte Como: Especificar a Fonte de Associação.

Especificando o Caminho ao Valor

Se sua fonte da associação é um objeto, você pode usar a propriedade Path para especificar o valor a ser usado em sua associação. Se você está associando dados XML , você usa a propriedade XPath para especificar o valor. Em alguns casos, pode ser aplicável usar a propriedade Path mesmo quando seus dados são XML. Por exemplo, se você quer acessar a propriedade Nome de um XmlNode retornado (como um resultado de um pedido XPath), você deve usar a propriedade Path conjuntamente com a propriedade XPath.

Para mais informações sobre sintaxe e exemplos, consulte as páginas das propriedades Path e XPath.

Note que embora tenhamos enfatizado que Path para o valor a ser usado é um dos quatro componentes necessários para uma associação, nos cenários em que você quer associar um objeto inteiro, o valor a ser usado seria o mesmo que o objeto fonte da associação. Nesses casos, é aplicável não especificar um Path. Considere o exemplo a seguir:

<ListBox ItemsSource="{Binding}"
         IsSynchronizedWithCurrentItem="true"/>

O exemplo acima usa a sintaxe de ligação vazia: {Ligação}. Neste caso, o ListBox herda o Contexto de Dados de um elemento DockPanel pai (não mostrado nesse exemplo). Quando o caminho não é especificado, o padrão é associar ao objeto inteiro. Em outras palavras, neste exemplo, o caminho oi deixado de fora porque estamos associando a propriedade ItemsSource ao objeto inteiro. (Consulte a seção Associando a Coleções para uma discussão aprofundada.)

Ao invés de associar a uma coleção, este cenário também é útil quando você quer associar a um objeto inteiro ao invés de somente uma única propriedade de um objeto. Por exemplo, seu objeto fonte é do tipo string e você simplesmente quer associar a string. Outro cenário comum é quando você quer associar um elemento a um objeto com várias propriedades.

Note que você pode precisar aplicar uma lógica personalizada para que os dados tenham significado para a propriedade alvo associada. A lógica personalizada pode ser na forma de um conversor personalizado (se o conversor padrão de tipos não existir). Consulte Conversão de Dados para informações sobre conversores.

Associação e Expressão de Associação

Antes de entrar em outras funcionalidades e usos de associação de dados, seria útil introduzir a classe BindingExpression. Como você viu nas seções anteriores, a classe Binding é a classe de alto nível para a declaração de uma associação; a classe Binding fornece várias propriedade que permitem você especificar as características de uma associação. Uma classe relacionada, BindingExpression, é o objeto subjacente que mantém a conexão entre a fonte e o alvo. Uma associação contém todas informações que podem ser compartilhadas através de várias expressões de associação. Uma BindingExpression é uma expressão de instância que não pode ser compartilhada e contém todas as informações de instância da Binding.

Por exemplo, considere o seguinte, onde myDataObject é uma instância da classe MyData , myBinding é o objeto Binding fonte, e a classe MyData é a classe definida que contém a propriedade string MyDataProperty. Este exemplo associa o conteúdo texto de um mytext, uma instância de TextBlock, ao MyDataProperty.

Dim data1 As New MyData(DateTime.Now)
Dim binding1 As New Binding("MyDataProperty")
binding1.Source = data1
Me.myText.SetBinding(TextBlock.TextProperty, binding1)
//make a new source
  MyData myDataObject = new MyData(DateTime.Now);      
  Binding myBinding = new Binding("MyDataProperty");
  myBinding.Source = myDataObject;
  myText.SetBinding(TextBlock.TextProperty, myBinding);

Você pode usar o mesmo objeto myBinding para criar outras associações. Por exemplo, você pode usar o objeto myBinding para associar o conteúdo texto a uma caixa de checar ao MyDataProperty. Naquele cenário, haverá duas instâncias de BindingExpression compartilhando o objeto myBinding.

Um objeto BindingExpression pode ser obtido por meio do valor de retorno da chamada de GetBindingExpression em um objeto associado a dados. Os seguintes tópicos demonstram alguns usos da classe BindingExpression:

Conversão de Dados

No exemplo anterior, o botão é vermelho porquê sua propriedade Background é associada a uma propriedade string com o valor "Red". Isto funciona porque o conversor de tipos é presente para o tipo Brush converter um valor string para um Brush.

Para adicionar esta informação a figura na seção Criando uma Associação, o diagrama fica que nem o seguinte:

Diagrama de associação de dados

Entretanto, e se ao invés de ter a propriedade de tipo string seu objeto fonte da associação tem uma propriedade Color do tipo Color? Neste caso, para que a associação funcione você deve primeiro transformar o valor da propriedade Color em algo que a propriedade Background aceite. Você precisaria criar um conversor personalizado que implementa a interface IValueConverter, como no seguinte exemplo:

[ValueConversion(typeof(Color), typeof(SolidColorBrush))]
public class ColorBrushConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color color = (Color)value;
        return new SolidColorBrush(color);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

A página de referência IValueConverter fornece mais informações.

Agora que o conversor personalizado é usado no lugar da conversão padrão, nosso diagrama fica assim:

Diagrama de associação de dados

Para reiterar, conversores padrão podem estar disponíveis porque conversores de tipo estão presentes no tipo sendo associado. Este comportamento depende em quais conversores de tipo disponíveis no alvo. Em caso de dúvida, crie seu próprio conversor.

Em seguida estão alguns cenários típicos onde faz sentido implementar um conversor de dados:

  • Seus dados devem ser exibidos de maneira diferente, dependendo da cultura. Por exemplo, você talvez queira implementar um conversor de moeda ou um conversor de calendário data/hora baseado nos valores ou padrões utilizados em uma cultura em particular.

  • Os dados sendo usados não necessariamente precisam modificar o valor texto da propriedade, mas para modificar alguns outros valores, como a fonte de uma imagem, ou a cor e estilo de exibição de texto. Conversores podem ser usados nesta instância convertendo a associação de uma propriedade que pode não parecer apropriada, como a associar um campo texto a uma propriedade Background de uma célula de tabela.

  • Mais de um controle ou múltiplas propriedades de controle são associadas a um mesmo dado. Neste caso, a associação primária pode simplesmente exibir o texto, onde outras associações lidam com questões específicas de exibição, mas ainda usam a mesma associação como fonte de informação.

  • Até agora não discutimos MultiBinding, onde a propriedade alvo tem uma coleção de associações. No caso de um MultiBinding, você usa um IMultiValueConverter personalizado para produzir um valor final dos valores da associação. Por exemplo, cor pode ser computado dos valores vermelho, azul e verde, que podem ser valores de um ou diferentes objetos fonte de associação. Consulte a página da classe MultiBinding para exemplos e informação.

Associando a Coleções

Esta seção contém as seguintes subseções.

  • Como Implementar Coleções
  • Visualizações de Coleções

Um objeto fonte de associação pode ser tratado tanto como um objeto único cujas propriedades contém dados ou como uma coleção de objetos polimórficos que são frequentemente agrupados juntos (como os resultados de uma query em um banco de dados). Até agora só discutimos associação a objetos sozinhos, entretanto, associar a uma coleção de dados é um cenário comum. Por exemplo, um cenário comum é usar um ItemsControl como um ListBox, ListView, ou TreeView para exibir uma coleção de dados, como na aplicação mostrada na seção O Que é Associação de Dados?.

Felizmente, nosso diagrama básico ainda se aplica. Se você está associando um ItemsControl a uma coleção, o diagrama fica assim:

Diagrama de ItemsControl de associação de dados

Como mostrado neste diagrama, associar um ItemsControl a um objeto de coleção, a propriedade ItemsSource é a propriedade a ser usada. Você pode pensar da propriedade ItemsSource como o conteúdo de ItemsControl. Perceba que a associação é OneWay porque a propriedade ItemsSource suporta associação OneWay por padrão.

Como Implementar Coleções

Você pode enumerar sobre qualquer coleção que implemente a interface IEnumerable. Entretanto, para definir associações dinâmicas para que inserção e deleção na coleção atualizem a UI automaticamente, a coleção deve implementar a interface INotifyCollectionChanged. Esta interface expõe um evento que deve ser levantado sempre que a coleção subjacente é modificada.

WPF fornece a classe ObservableCollection<T>, que é uma implementação embutida de uma coleção de dados que expõe a interface INotifyCollectionChanged . Note que para suportar completamente a transferência de valores de dados de objetos fontes para objetos alvo, cada objeto em sua coleção que suporta propriedades associáveis deve também implementar a interface INotifyPropertyChanged. Para um exemplo, consulte VinculParar Para um exemplo de coleção. Para obter mais informações, consulte Visão geral sobre associação de fontes.

Antes de implementar sua própria coleção, considere usar ObservableCollection<T> ou uma das classes de coleção existentes, como uma List<T>, Collection<T>, e BindingList<T>, entre muitas outras. Se você tem um cenário avançado e quer implementar sua própria coleção, considere usar IList, que fornece uma coleção de objetos não genéricos que podem ser acessados individualmente por um índice e portanto a melhor performance.

Visualizações de Coleções

Uma vez que seu ItemsControl está associado a uma coleção de dados, você pode querer ordenar, filtrar ou agrupar os dados. Para fazê-lo, use visualização de coleções, que são classes que implementam a interface ICollectionView.

Esta seção contém as seguintes subseções.

  • O Que são Visualização de Coleções?
  • Como Criar uma Visualização
  • Classificação
  • Filtro
  • Agrupamento
  • Ponteiros de item corrente
  • Cenário de Associação Master-Detail

O Que são Visualização de Coleções?

Um modo de exibição de coleção é uma camada de uma coleção de fonte de vinculação permite que você navegar e exibir fonte coleção com base em classificar, filtrar e agrupar consultas sem alterar a própria coleção fonte subjacente. Um modo de exibição de coleção também mantém um ponteiro para o item corrente na coleção. Se a coleção fonte implementa a interface INotifyCollectionChanged , as modificações levantadas pelo evento CollectionChanged são propagadas para as visualizações.

Como visualizações não modificando as coleções fonte subjacente, cada coleção fonte pode ter múltiplas visualizações associadas. Por exemplo, você pode ter uma coleção de objetos Task. Com o uso das visualizações, você pode exibir os mesmos dados de maneiras diferentes. Por exemplo, no lado esquerdo de sua página você pode mostrar as tarefas ordenadas por prioridade, e no lado direito, agrupados por área.

Como Criar uma Visualização

Uma maneira de criar e usar uma visualização é instanciar o objeto de visualização diretamente e então usá-lo como a fonte da associação. Por exemplo, considere a aplicação Demonstração de ligação de dados mostrada na seção O que é Associação de Dados?. Na aplicação implementada , ListBox associa uma visualização sobre a coleção de dados ao invés da coleção de dados diretamente. O seguinte exemplo é extraído da aplicação Demonstração de ligação de dados. The CollectionViewSource classe é o Extensible Application Markup Language (XAML) proxy de uma classe que herda de CollectionView. Neste exemplo particular, o Source da visualização é associado a coleção AuctionItems (de tipo ObservableCollection<T>) do objeto atual da aplicação.

<Window.Resources>


...


<CollectionViewSource 
      Source="{Binding Source={x:Static Application.Current}, Path=AuctionItems}"   
      x:Key="listingDataView" />


...


</Window.Resources>

O recurso listingDataView então serve como a fonte da associação para os elementos nesta aplicação, como o ListBox:

<ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8"
    ItemsSource="{Binding Source={StaticResource listingDataView}}">


...


</ListBox>

Para criar outra visualização da mesma coleção, você pode criar outra instância CollectionViewSource e dá-la um nome x:Key diferente.

A tabela a seguir mostra quais tipos de dados de modo de exibição é criadas sistema autônomo o modo de exibição de coleção padrão ou por CollectionViewSource com base no tipo de coleção de fonte.

Tipo de coleção de fonte

Tipo de modo de exibição de coleção

Anotações

IEnumerable

Um tipo interno com base em CollectionView

Não é possível agrupar itens.

IList

ListCollectionView

Mais rápido.

IBindingList

BindingListCollectionView

Usando um modo de exibição padrão

Especificando um modo de exibição de coleção sistema autônomo uma fonte de vinculação é uma maneira de criar e usar um modo de exibição de coleção. WPF também cria um modo de exibição de coleção padrão para cada conjunto usado sistema autônomo uma fonte de vinculação. Se você BIND diretamente a uma coleção, WPF vincula-se ao seu modo de exibição padrão. Observe que esse modo de exibição padrão é compartilhado por todas sistema autônomo ligações à mesma coleção, para que uma alterar feita em um modo de exibição padrão por um controle limite ou código (sistema autônomo, por exemplo, classificação ou uma alterar do ponteiro corrente do item, discutido posteriormente) é refletido no todas sistema autônomo outras ligações ao mesmo conjunto.

Para pegar a visualização padrão, você usa o método GetDefaultView. Para um exemplo, consulte Como: Obter o Modo de Exibição Padrão de uma Coleção de Dados.

Exibições de coleção com ADO.NET DataTables

Para melhorar o desempenho, exibições de coleção para o ADO.NET DataTable ou DataView objetos delegado classificação e filtragem para o DataView. Isso faz a classificação e filtragem a ser compartilhado entre todos os modos de exibição de coleção da fonte de dados. Para ativar cada modo de exibição de coleção classificar e filtrar independentemente, inicializar cada modo de exibição de coleção com seu próprio DataView objeto.

Classificação

Como mencionado anteriormente, visualizações podem aplicar uma ordenação na coleção. Como existem na coleção subjacente, seus dados podem ou não ter uma ordem inerente relevante. A visualização sobre a coleção permite você impor um ordem, ou modificar a ordenação padrão, baseada no critério de comparação que você fornece. Como é uma visualização de dados baseada no cliente, um cenário comum é que o usuário possa querer ordenar colunas de dados tabulares por valores que a coluna corresponde. Usando visualizações, esta ordenação orientada pelo usuário pode ser aplicada, novamente sem realizar nenhuma modificação na coleção subjacente ou mesmo precisando requisitar pelo conteúdo da coleção. Para um exemplo, consulte Como: Sort a GridView Column When a Header Is Clicked.

O seguinte exemplo mostra a lógica da CheckBox "Ordenar por categoria e dada" de uma aplicação UI na seção O Que é Associação de Dados?:

private void AddSorting(object sender, RoutedEventArgs args)
{
    // This sorts the items first by Category and within each Category,
    // by StartDate. Notice that because Category is an enumeration,
    // the order of the items is the same as in the enumeration declaration
    listingDataView.SortDescriptions.Add(
        new SortDescription("Category", ListSortDirection.Ascending));
    listingDataView.SortDescriptions.Add(
        new SortDescription("StartDate", ListSortDirection.Ascending));
}

Filtro

Visualizações podem também aplicar um filtro a uma coleção Isto significa que embora um item possa existir na coleção, esta visualização em particular pretende mostrar somente um certo subconjunto da coleção inteira. Você pode filtrar baseado em uma condição nos dados. Por exemplo, como é feito na aplicação na seção O Que é Associação de dados?, o CheckBox "Mostre somente barganhas" contém a lógica para filtrar os itens que custam $25 ou mais. O seguinte código é executado para definir ShowOnlyBargainsFilter como o manipulador de eventos Filter quando o CheckBox é selecionado:

listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);

O manipulador de eventos ShowOnlyBargainsFilter tem a seguinte implementação:

private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
{
    AuctionItem product = e.Item as AuctionItem;
    if (product != null)
    {
        // Filter out products with price 25 or above
        if (product.CurrentPrice < 25)
        {
            e.Accepted = true;
        }
        else
        {
            e.Accepted = false;
        }
    }
}

Se você está usando uma das classes CollectionView diretamente ao invés de CollectionViewSource, você usaria a propriedade Filter para especificar um callback. Para um exemplo, consulte Como: Filtrar dados em um modo de exibição.

Agrupamento

Exceto para a classe interna que exibe um IEnumerable coleção, todos os modos de exibição de coleção suportam a funcionalidade de agrupamento, que permite ao usuário particionar a coleção no modo de exibição de coleção em grupos lógicos. Os grupos podem ser explícitos, quando o usuário fornece uma lista de grupos, ou implícito, quando os grupos são gerados dinamicamente dependendo dos dados.

O seguinte exemplo mostra a lógica do CheckBox "Agrupe por categoria" .

// This groups the items in the view by the property "Category"
PropertyGroupDescription groupDescription = new PropertyGroupDescription();
groupDescription.PropertyName = "Category";
listingDataView.GroupDescriptions.Add(groupDescription);

Para outro exemplo de agrupamento, consulte Como: Group Items in a ListView That Implements a GridView.

Ponteiros de item corrente

Visualizações também suportam a noção de item atual. Você pode navegar através de objetos em uma visualização de coleção. sistema autônomo você navega, você está movendo um ponteiro de item que lhe permite recuperar o objeto existe nesse local específico na coleção. Para um exemplo, consulte Como: Navigate Through the Objects in a Data CollectionView.

Porque o WPF vincula a uma coleção somente por usando um modo de exibição (um modo de exibição que você especificar, ou modo de exibição da coleção padrão), todas as ligações para coleções têm um ponteiro corrente do item. Ao ligar a um modo de exibição, barra / / ("/") de caractere em umPath valor designa o item do modo de exibição corrente. No exemplo a seguir, o contexto de dados é uma exibição de coleção. A primeira linha vincula à coleção. A segunda linha liga o item corrente na coleção. A terceira linha vincula o Description propriedade do item corrente na coleção.

<Button Content="{Binding }" />
<Button Content="{Binding Path=/}" />
<Button Content="{Binding Path=/Description}" /> 

A sintaxe de barra / e a propriedade também pode ser empilhada para atravessar uma hierarquia de coleções. O exemplo a seguir vincula ao item corrente de uma coleção denominada Offices, que é uma propriedade do item corrente da coleção de fonte.

<Button Content="{Binding /Offices/}" />

O ponteiro corrente do item pode ser afetado por qualquer classificação ou filtragem é aplicada à coleção. Classificação preserva o ponteiro do item corrente no último item selecionado, mas agora é reestruturar o modo de exibição de coleção ao redor dele. (Talvez o item selecionado foi no início da lista antes, mas agora o item selecionado pode estar em algum lugar no meio). Filtragem preserva o item selecionado se essa seleção permanece após a filtragem no modo de exibição. Caso contrário, o ponteiro corrente do item é conjunto para o primeiro item da exibição de coleção filtrada.

Cenário de Associação Master-Detail

A noção de um item atual é útil não só para navegação de itens em uma coleção, mas também par ao cenário de associação master-detail. Considere a aplicação UI na seção O Que é Associação de Dados? novamente. Naquela aplicação, a seleção dentro da ListBox determina o conteúdo exibido no ContentControl. Para colocar de outra forma, quando um item ListBox é selecionado, o ContentControl exibe os detalhes do item selecionado.

Você pode implementar o cenário master-detail simplesmente tendo dois ou mais controles associados a mesma visualização. O seguinte exemplo do Demonstração de ligação de dados mostra a marcação do ListBox e o ContentControl você vê na aplicação UI na seção O Que é Associação de Dados:

<ListBox Name="Master" Grid.Row="2" Grid.ColumnSpan="3" Margin="8"
    ItemsSource="{Binding Source={StaticResource listingDataView}}">


...


</ListBox>


...


<ContentControl Name="Detail" Grid.Row="3" Grid.ColumnSpan="3" 
        Content="{Binding Source={StaticResource listingDataView}}" 
        ContentTemplate="{StaticResource detailsProductListingTemplate}" 
        Margin="9,0,0,0"/>

Note que ambos os controles são associados a mesma fonte, o recurso estático listingDataView (veja a definição deste recurso na seção Como Criar uma Visualização). Isto funciona porque quando um objeto único (o ContentControl neste caso) é associado a uma visualização de coleção, ele automaticamente associa ao CurrentItem da visualização. Note que objetos CollectionViewSource automaticamente sincronizam atualidade e seleção. Se seu controle lista não está associado a um objeto CollectionViewSource como neste exemplo, então você precisaria definir sua propriedade IsSynchronizedWithCurrentItem para true para isto funcionar.

Para outros exemplos, consulte Como: Bind to a Collection and Display Information Based on Selection e Como: Use the Master-Detail Pattern with Hierarchical Data.

Você deve ter percebido que o exemplo acima usa um padrão. Na verdade, os dados não seriam exibidos da maneira que gostaríamos sem o uso de padrões (o usado explicitamente pelo ContentControl e o usado implicitamente peloListBox). Agora nós vamos a padronização de dados na próxima seção.

Padronização de Dados

Sem o uso de padrões de dados, nossa aplicação UI na seção O Que é Associação de Dados ficaria parecida com o seguinte:

Demonstração de associação de dados sem modelos de dados

Conforme mostrado no exemplo na seção anterior, a ListBox controle e o ContentControl são vinculados a objeto da coleção inteira (ou mais especificamente, o modo de exibição sobre o objeto de coleção) de AuctionItemsistema autônomo. Sem instruções específicas como exibir a coleta de dados, a ListBox está exibindo uma representação de seqüência de cada objeto da coleção subjacente e o ContentControl está exibindo uma representação de seqüência do objeto a que está limite.

Para resolver o problema, o aplicativo define DataTemplates. As shown in the example in the previous section, the ContentControl explicitly uses the detailsProductListingTemplate DataTemplate. O controle ListBox usa implicitamente o seguinte DataTemplate quando exibindo os objetos AuctionItem na coleção:

<DataTemplate DataType="{x:Type src:AuctionItem}">
    <Border BorderThickness="1" BorderBrush="Gray"
            Padding="7" Name="border" Margin="3" Width="500">
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="20"/>
            <ColumnDefinition Width="86"/>
            <ColumnDefinition Width="*"/>
          </Grid.ColumnDefinitions>

            <Polygon Grid.Row="0" Grid.Column="0" Grid.RowSpan="4"
                     Fill="Yellow" Stroke="Black" StrokeThickness="1"
                     StrokeLineJoin="Round" Width="20" Height="20"
                     Stretch="Fill"
                     Points="9,2 11,7 17,7 12,10 14,15 9,12 4,15 6,10 1,7 7,7"
                     Visibility="Hidden" Name="star"/>

            <TextBlock Grid.Row="0" Grid.Column="1" Margin="0,0,8,0"
                       Name="descriptionTitle"
                       Style="{StaticResource smallTitleStyle}">Description:</TextBlock>
            <TextBlock Name="DescriptionDTDataType" Grid.Row="0" Grid.Column="2" 
                Text="{Binding Path=Description}" 
                Style="{StaticResource textStyleTextBlock}"/>

            <TextBlock Grid.Row="1" Grid.Column="1" Margin="0,0,8,0"
                       Name="currentPriceTitle"
                       Style="{StaticResource smallTitleStyle}">Current Price:</TextBlock>
            <StackPanel Grid.Row="1" Grid.Column="2" Orientation="Horizontal">
                <TextBlock Text="$" Style="{StaticResource textStyleTextBlock}"/>
                <TextBlock Name="CurrentPriceDTDataType" 
                    Text="{Binding Path=CurrentPrice}" 
                    Style="{StaticResource textStyleTextBlock}"/>
            </StackPanel>
        </Grid>
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=SpecialFeatures}">
            <DataTrigger.Value>
                <src:SpecialFeatures>Color</src:SpecialFeatures>
            </DataTrigger.Value>
          <DataTrigger.Setters>
            <Setter Property="BorderBrush" Value="DodgerBlue" TargetName="border" />
            <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
            <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
            <Setter Property="BorderThickness" Value="3" TargetName="border" />
            <Setter Property="Padding" Value="5" TargetName="border" />
          </DataTrigger.Setters>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=SpecialFeatures}">
            <DataTrigger.Value>
                <src:SpecialFeatures>Highlight</src:SpecialFeatures>
            </DataTrigger.Value>
            <Setter Property="BorderBrush" Value="Orange" TargetName="border" />
            <Setter Property="Foreground" Value="Navy" TargetName="descriptionTitle" />
            <Setter Property="Foreground" Value="Navy" TargetName="currentPriceTitle" />
            <Setter Property="Visibility" Value="Visible" TargetName="star" />
            <Setter Property="BorderThickness" Value="3" TargetName="border" />
            <Setter Property="Padding" Value="5" TargetName="border" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Com o uso desses dois DataTemplates, a Interface de Usuário resultante é a mostrada na seção O Que é Associação de Dados?. Como você pode ver a partir da screenshot, além de permitir você colocar os dados nos seus controles, DataTemplates permitem você definir exibições para seus dados. Por exemplo, DataTriggers são usados no DataTemplate acima para que AuctionItems com valor SpecialFeatures de HighLight sejam exibidos com uma cor laranja e uma estrela.

Para mais informações sobre padrões de dados, consulte o Visão geral sobre Templating de dados.

Validação de Dados

Esta seção contém as seguintes subseções.

  • Associando Regras de Validação com uma Associação.
  • Fornecendo Feedback Visual
  • Processo de Validação

A maioria das aplicações que recebem entrada do usuário precisam de validação lógica para garantir que o usuário imputou as informações esperadas. As verificações de validação podem ser baseadas em tipo, domínio, formato ou outros requisitos específicos de aplicação. Esta seção discute como validação de dados funciona no WPF.

Associando Regras de Validação com uma Associação.

O modelo de associação de dados de WPF permite você associar ValidationRules com o seu objeto Binding. Por exemplo, o seguinte é o XAML para o Add Product Listing "Start Price" TextBox da seção O Que é Associação de dados:

<TextBox Name="StartPriceEntryForm" Grid.Row="2" Grid.Column="1"
    Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5">
  <TextBox.Text>
    <Binding Path="StartPrice" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <ExceptionValidationRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

The ValidationRules propriedade tem uma coleção de ValidationRule objetos. ExceptionValidationRule é um ValidationRule que verifica se há exceções geradas durante a atualização da propriedade fonte de vinculação. Neste exemplo específico, a propriedade de fonte da vinculação é StartPrice (do tipo inteiro) e a propriedade de destino é TextBox.Text. Quando o usuário imputa um valor que não pode ser convertido para inteiro, uma exceção é gerada, fazendo a associação ser marcada como inválida.

Você também pode criar sua própria regra de validação derivando da classe ValidationRule e implementando o método Validate. O seguinte exemplo mostra a regra usada pelo Add Product Listing "Start Date" TextBox da seção O Que é Associação de Dados?:

class FutureDateRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        DateTime date;
        try
        {
            date = DateTime.Parse(value.ToString());
        }
        catch (FormatException)
        {
            return new ValidationResult(false, "Value is not a valid date.");
        }
        if (DateTime.Now.Date > date)
        {
            return new ValidationResult(false, "Please enter a date in the future.");
        }
        else
        {
            return ValidationResult.ValidResult;
        }
    }
}

O StartDateEntryForm TextBox usa este FutureDateRule, como mostrado no seguinte exemplo:

<TextBox Name="StartDateEntryForm" Grid.Row="3" Grid.Column="1" 
    Validation.ErrorTemplate="{StaticResource validationTemplate}" 
    Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5">
    <TextBox.Text>
        <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged" 
            Converter="{StaticResource dateConverter}" >
            <Binding.ValidationRules>
                <src:FutureDateRule />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Note que porque o valor UpdateSourceTrigger é PropertyChanged, o sistema de associação atualiza o valor da fonte em cada tecla pressionada, o que significa que também verifica cada regra na coleção ValidationRules em cada tecla pressionada. Discutiremos isto mais tarde na seção Processo de Validação.

Fornecendo Feedback Visual

Se um usuário entra com um valor inválido, você pode querer fornecer algum feedback sobre o erro na aplicação UI. Uma maneira de fornecer tal feedback é definir a propriedade Validation.ErrorTemplate anexa para um ControlTemplate personalizado. Como visto na seção anterior, o StartDateEntryForm TextBox usa um ErrorTemplate chamado validationTemplate. O seguinte exemplo mostra a definição do validationTemplate:

<ControlTemplate x:Key="validationTemplate">
  <DockPanel>
    <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
    <AdornedElementPlaceholder/>
  </DockPanel>
</ControlTemplate>

O elemento AdornedElementPlaceholder especifica onde o controle sendo adornado deve ser colocado.

Adicionalmente, você também pode usar um ToolTip para exibir a mensagem de erro. Ambos os StartDateEntryForm e o StartPriceEntryForm TextBoxes usam o estilo textStyleTextBox, que cria um ToolTip que exibe a mensagem de erro. O seguinte exemplo mostra a definição de textStyleTextBox. The attached property Validation.HasError is true when one or more of the bindings on the properties of the bound element are in error.

<Style x:Key="textStyleTextBox" TargetType="TextBox">
  <Setter Property="Foreground" Value="#333333" />
  <Setter Property="MaxLength" Value="40" />
  <Setter Property="Width" Value="392" />
  <Style.Triggers>
    <Trigger Property="Validation.HasError" Value="true">
      <Setter Property="ToolTip"
        Value="{Binding RelativeSource={RelativeSource Self},
                        Path=(Validation.Errors)[0].ErrorContent}"/>
    </Trigger>
  </Style.Triggers>
</Style>

Com o ErrorTemplate personalizado e o ToolTip, e StartDateEntryForm TextBox parece com o seguinte quando há um erro de validação:

Erro de validação de associação de dados

Se seu Binding possui regras de validação associadas mas você não especificou um ErrorTemplate no controle associado, um ErrorTemplate padrão será usado para notificar usuários quando há erro de validação. O ErrorTemplate padrão é um padrão de controle que define uma borda vermelha em uma camada adornada. Com o ErrorTemplate padrão e o ToolTip, o UI do StartPriceEntryForm TextBox parece com o seguinte quando há um erro de validação:

Erro de validação de associação de dados

Para um exemplo de como fornecer a lógica para validar todos os controles em uma caixa de diálogo, consulte a seção Caixas de Diálogo Personalizadas em Dialog Boxes Overview.

Processo de Validação

Validação ocorre geralmente quando o valor de um destino é transferido para a propriedade de fonte da vinculação. Isso ocorre em TwoWay e OneWayToSource Ligações. Para reiterar, o que causa uma atualização da fonte depende do valor da propriedade UpdateSourceTrigger, como descrito na seção O Que Causa Atualização de Fonte.

A seguir descreve o validação processo. Observe que, se um erro de validação ou Outros tipo de erro ocorre em qualquer time durante esse processo, o processo é interrompido.

  1. O mecanismo de ligação verifica se há qualquer personalizado ValidationRule objetos definidos cujos ValidationStep é conjunto para RawProposedValue para que Binding, caso em que ele chama o Validate método em cada ValidationRule passe até que uma delas é executado em um erro ou até que todos eles.

  2. O mecanismo de ligação em seguida, chama o conversor, se houver.

  3. Se o conversor for bem-sucedida, o mecanismo de ligação verifica se há qualquer personalizado ValidationRule objetos definidos cujos ValidationStep é conjunto para ConvertedProposedValue para que Binding, caso em que ele chama o Validate método em cada ValidationRule que tem ValidationStep conjunto para ConvertedProposedValue passe até que uma delas é executado em um erro ou até que todos eles.

  4. O mecanismo de ligação define a propriedade de fonte.

  5. O mecanismo de ligação verifica se há qualquer personalizado ValidationRule objetos definidos cujos ValidationStep é definido como UpdatedValue para que Binding, caso em que ele chama o Validate método em cada ValidationRule que tem ValidationStep definido como UpdatedValue passe até que uma delas é executado em um erro ou até que todos eles.

  6. O mecanismo de ligação verifica se há qualquer personalizado ValidationRule objetos definidos cujos ValidationStep é definido como CommittedValue para que Binding, caso em que ele chama o Validate método em cada ValidationRule que tem ValidationStep definido como CommittedValue passe até que uma delas é executado em um erro ou até que todos eles.

If a ValidationRule não passe a qualquer momento durante este processo, o mecanismo de vinculação cria um ValidationError objeto e o adiciona para o Validation.Errors coleção de elemento limite. Before the binding engine runs the ValidationRule objects at any given step, it removes any ValidationError that was added to the Validation.Errors attached property of the bound element during that step. Por exemplo, se um ValidationRule cujo ValidationStep é conjunto para UpdatedValue Falha, na próxima vez em que o processo de validação ocorre, enging ligação remove que ValidationError imediatamente antes ele chama qualquer ValidationRule que tem ValidationStep conjunto para UpdatedValue.

When Validation.Errors is not empty, the Validation.HasError attached property of the element is set to true. Also, if the NotifyOnValidationError property of the Binding is set to true, then the binding engine raises the Validation.Error attached event on the element.

Also note that a valid value transfer in either direction (target to source or source to target) clears the Validation.Errors attached property.

Se a ligação tem um ExceptionValidationRule associado a ele e uma exceção é lançada quando o mecanismo de ligação define a fonte, o mecanismo de ligação verifica se há um UpdateSourceExceptionFilter. Você tem a opção de usar o callback UpdateSourceExceptionFilter para fornecer um manipulador personalizado para lidar com exceções. Se um UpdateSourceExceptionFilter não é especificado na Binding, o mecanismo de vinculação cria um ValidationError com a exceção e o adiciona para o Validation.Errors coleção de elemento limite.

Mecanismo de Depuração

Você pode definir a propriedade anexa PresentationTraceSources.TraceLevel em um objeto associativo para receber informação sobre o estado de uma associação específica.

Consulte também

Tarefas

Como: Bind to the Results of a LINQ Query

Demonstração de ligação de dados

Conceitos

O que há de novo no Windows Presentation Foundation Versão 3.5

Otimizando o desempenho: Ligação de Dados

Referência

DataErrorValidationRule

Outros recursos

Exemplos de ligação de dados

Data Binding How-to Topics

Date

History

Motivo

Julho de 2008

Atualizado o Processo de validação seção para refletir as alterações para o serviço empacotar 1.

Alteração de recurso do SP1.