Visão geral da ligação de dados no WPFData binding overview in WPF

A vinculação de dados no Windows Presentation Foundation (WPF) fornece uma maneira simples e consistente para que os aplicativos apresentem e interajam com os dados.Data binding in Windows Presentation Foundation (WPF) provides a simple and consistent way for apps to present and interact with data. Os elementos podem ser associados a dados de uma variedade de fontes de dados na forma de objetos .NET e XML.Elements can be bound to data from a variety of data sources in the form of .NET objects and XML. Qualquer como ContentControl Button e qualquer ItemsControl , como ListBox e ListView , têm funcionalidade interna para habilitar o estilo flexível de itens de dados individuais ou coleções de itens de dados.Any ContentControl such as Button and any ItemsControl, such as ListBox and ListView, have built-in functionality to enable flexible styling of single data items or collections of data items. É possível gerar exibições com classificação, filtragem e agrupamento dos dados.Sort, filter, and group views can be generated on top of the data.

A funcionalidade de vinculação de dados no WPF tem várias vantagens em relação aos modelos tradicionais, incluindo suporte inerente à vinculação de dados por uma ampla variedade de propriedades, representação flexível da interface do usuário de dados e separação clara da lógica de negócios da interface do usuário.The data binding functionality in WPF has several advantages over traditional models, including inherent support for data binding by a broad range of properties, flexible UI representation of data, and clean separation of business logic from UI.

Este artigo aborda primeiro os conceitos fundamentais para a ligação de dados do WPF e, em seguida, aborda o uso da Binding classe e de outros recursos de vinculação de dados.This article first discusses concepts fundamental to WPF data binding and then covers the usage of the Binding class and other features of data binding.

Importante

A documentação do guia da área de trabalho está em construção.The Desktop Guide documentation is under construction.

O que é a associação de dados?What is data binding?

A vinculação de dados é o processo que estabelece uma conexão entre a interface do usuário do aplicativo e os dados exibidos.Data binding is the process that establishes a connection between the app UI and the data it displays. Se a associação possui configurações corretas e os dados fornecem notificações adequadas, quando os dados mudam de valor, os elementos que são associados a dados refletem as mudanças automaticamente.If the binding has the correct settings and the data provides the proper notifications, when the data changes its value, the elements that are bound to the data reflect changes automatically. A vinculação de dados também poderá significar que, se houver uma alteração de uma representação externa dos dados em um elemento, os dados subjacentes poderão ser atualizados automaticamente para refletir essa alteração.Data binding can also mean that if an outer representation of the data in an element changes, then the underlying data can be automatically updated to reflect the change. Por exemplo, se o usuário editar o valor em um TextBox elemento, o valor dos dados subjacentes será atualizado automaticamente para refletir essa alteração.For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.

Um uso típico da vinculação de dados é posicionar dados de configuração de servidor ou local em formulários ou outros controles de interface do usuário.A typical use of data binding is to place server or local configuration data into forms or other UI controls. No WPF, esse conceito é expandido para incluir a associação de uma ampla variedade de propriedades a uma variedade de fontes de dados.In WPF, this concept is expanded to include binding a broad range of properties to a variety of data sources. No WPF, as propriedades de dependência de elementos podem ser associadas a objetos .NET (incluindo objetos ADO.NET ou objetos associados a serviços Web e propriedades da Web) e dados XML.In WPF, dependency properties of elements can be bound to .NET objects (including ADO.NET objects or objects associated with Web Services and Web properties) and XML data.

Para obter um exemplo de vinculação de dados, confira a interface do usuário do aplicativo a seguir da demonstração de vinculação de dados, que exibe uma lista de itens de leilão.For an example of data binding, take a look at the following app UI from the Data Binding Demo, which displays a list of auction items.

Captura de tela de exemplo de vinculação de dadosData binding sample screenshot

O aplicativo demonstra os seguintes recursos de vinculação de dados:The app demonstrates the following features of data binding:

  • O conteúdo da caixa de listagem está associado a uma coleção de objetos AuctionItem .The content of the ListBox is bound to a collection of AuctionItem objects. Um objeto AuctionItem tem propriedades como Descrição, StartPrice, StartDate, Category, SpecialFeaturese assim por diante.An AuctionItem object has properties such as Description, StartPrice, StartDate, Category, SpecialFeatures, and so on.

  • Os dados (objetosAuctionItem ) exibidos no ListBox são modelados de forma que a descrição e o preço atual sejam mostrados para cada item.The data (AuctionItem objects) displayed in the ListBox is templated so that the description and the current price are shown for each item. O modelo é criado usando um DataTemplate .The template is created by using a DataTemplate. Além disso, a aparência de cada item depende do valor de SpecialFeatures do AuctionItem sendo exibido.In addition, the appearance of each item depends on the SpecialFeatures value of the AuctionItem being displayed. Se o valor SpecialFeatures do AuctionItem for Color, o item terá uma borda azul.If the SpecialFeatures value of the AuctionItem is Color, the item has a blue border. Se o valor for Highlight, o item terá uma borda laranja e uma estrela.If the value is Highlight, the item has an orange border and a star. A seção Modelos de dados fornece informações sobre modelagem de dados.The Data Templating section provides information about data templating.

  • O usuário pode agrupar, filtrar ou classificar os dados usando o CheckBoxes fornecido.The user can group, filter, or sort the data using the CheckBoxes provided. Na imagem acima, a categoria agrupar por e classificar por categoria e data CheckBoxes são selecionados.In the image above, the Group by category and Sort by category and date CheckBoxes are selected. Você talvez tenha observado que os dados estão agrupados com base na categoria do produto e que o nome da categoria está em ordem alfabética.You may have noticed that the data is grouped based on the category of the product, and the category name is in alphabetical order. É difícil perceber isto na imagem, mas os itens também são classificados por data de início dentro de cada categoria.It is difficult to notice from the image but the items are also sorted by the start date within each category. A classificação é feita usando uma exibição de coleção.Sorting is done using a collection view. A seção associando a coleções discute exibições de coleção.The Binding to collections section discusses collection views.

  • Quando o usuário seleciona um item, ContentControl exibe os detalhes do item selecionado.When the user selects an item, the ContentControl displays the details of the selected item. Essa experiência é chamada de cenário de detalhes mestre.This experience is called the Master-detail scenario. A seção cenário de detalhes mestre fornece informações sobre esse tipo de associação.The Master-detail scenario section provides information about this type of binding.

  • O tipo da propriedade StartDate é DateTime , que retorna uma data que inclui a hora para o milissegundo.The type of the StartDate property is DateTime, which returns a date that includes the time to the millisecond. Nesse aplicativo, um conversor personalizado foi usado para que uma cadeia de caracteres de data mais curta seja exibida.In this app, a custom converter has been used so that a shorter date string is displayed. A seção conversão de dados fornece informações sobre conversores.The Data conversion section provides information about converters.

Quando o usuário seleciona o botão Adicionar produto , o formulário a seguir é exibido.When the user selects the Add Product button, the following form comes up.

Página Adicionar Listagem de produtosAdd Product Listing page

O usuário pode editar os campos no formulário, Visualizar a listagem de produtos usando os painéis de visualização curtos ou detalhados e selecionar Submit para adicionar a nova listagem de produtos.The user can edit the fields in the form, preview the product listing using the short or detailed preview panes, and select Submit to add the new product listing. Todas as configurações existentes de agrupamento, filtragem e classificação serão aplicadas à nova entrada.Any existing grouping, filtering and sorting settings will apply to the new entry. Neste caso em particular, o item inserido na imagem acima será exibido como o segundo item dentro da categoria Computador.In this particular case, the item entered in the above image will be displayed as the second item within the Computer category.

Não mostrada nesta imagem é a lógica de validação fornecida na data de início TextBox .Not shown in this image is the validation logic provided in the Start Date TextBox. Se o usuário inserir uma data inválida (formatação inválida ou uma data anterior), o usuário será notificado com um ToolTip e um ponto de exclamação vermelho ao lado do TextBox .If the user enters an invalid date (invalid formatting or a past date), the user will be notified with a ToolTip and a red exclamation point next to the TextBox. A seção Validação de dados discute como criar lógica de validação.The Data Validation section discusses how to create validation logic.

Antes de entrar nos diferentes recursos de ligação de dados descritos acima, discutiremos primeiro os conceitos fundamentais que são essenciais para entender a ligação de dados do WPF.Before going into the different features of data binding outlined above, we will first discuss the fundamental concepts that are critical to understanding WPF data binding.

Conceitos básicos de vinculação de dadosBasic data binding concepts

Independentemente do elemento que você está associando e da natureza de sua fonte de dados, cada associação sempre segue o modelo ilustrado pela figura a seguir.Regardless of what element you are binding and the nature of your data source, each binding always follows the model illustrated by the following figure.

Diagrama que mostra o modelo básico de ligação de dados.

Como mostra a figura, a vinculação de dados é essencialmente a ponte entre seu destino de associação e sua fonte de associação.As the figure shows, data binding is essentially the bridge between your binding target and your binding source. A figura demonstra os seguintes conceitos fundamentais de ligação de dados do WPF:The figure demonstrates the following fundamental WPF data binding concepts:

  • Normalmente, cada associação tem quatro componentes:Typically, each binding has four components:

    • Um objeto de destino de associação.A binding target object.
    • Uma propriedade de destino.A target property.
    • Uma origem de associação.A binding source.
    • Um caminho para o valor na origem da associação a ser usado.A path to the value in the binding source to use.

    Por exemplo, se você deseja associar o conteúdo de um TextBox à Employee.Name propriedade, o objeto de destino é o TextBox , a propriedade de destino é a Text propriedade, o valor a ser usado é nomee o objeto de origem é o objeto Employee .For example, if you want to bind the content of a TextBox to the Employee.Name property, your target object is the TextBox, the target property is the Text property, the value to use is Name, and the source object is the Employee object.

  • A propriedade de destino deve ser uma propriedade de dependência.The target property must be a dependency property. A maioria das UIElement Propriedades são propriedades de dependência e a maioria das propriedades de dependência, exceto somente leitura, dá suporte à associação de dados por padrão.Most UIElement properties are dependency properties, and most dependency properties, except read-only ones, support data binding by default. (Somente tipos derivados de DependencyObject podem definir propriedades de dependência; e todos os UIElement tipos derivam de DependencyObject .)(Only types derived from DependencyObject can define dependency properties; and all UIElement types derive from DependencyObject.)

  • Embora não seja mostrado na figura, deve-se observar que o objeto de origem da associação não está restrito a ser um objeto .NET personalizado.Although not shown in the figure, it should be noted that the binding source object is not restricted to being a custom .NET object. A ligação de dados do WPF dá suporte a dados na forma de objetos .NET e XML.WPF data binding supports data in the form of .NET objects and XML. Para fornecer alguns exemplos, sua fonte de associação pode ser um UIElement , qualquer objeto de lista, um ADO.net ou um objeto de serviços Web, ou um XmlNode que contém os dados XML.To provide some examples, your binding source may be a UIElement, any list object, an ADO.NET or Web Services object, or an XmlNode that contains your XML data. Para obter mais informações, consulte visão geral de fontes de associação.For more information, see Binding sources overview.

É importante lembrar que quando você estiver estabelecendo uma associação, você está associando um destino de associação a uma fonte de associação.It is important to remember that when you are establishing a binding, you are binding a binding target to a binding source. Por exemplo, se você estiver exibindo alguns dados XML subjacentes em um ListBox usando Associação de dados, você está ligando seus ListBox para os dados XML.For example, if you are displaying some underlying XML data in a ListBox using data binding, you are binding your ListBox to the XML data.

Para estabelecer uma associação, use o Binding objeto.To establish a binding, you use the Binding object. O restante deste artigo aborda muitos dos conceitos associados a e algumas das propriedades e do uso do Binding objeto.The rest of this article discusses many of the concepts associated with and some of the properties and usage of the Binding object.

Direção do fluxo de dadosDirection of the data flow

Conforme indicado na seta na figura anterior, o fluxo de dados de uma associação pode ir do destino de associação para a fonte de associação (por exemplo, o valor de origem é alterado quando um usuário edita o valor de a TextBox ) e/ou da origem da Associação para o destino de associação (por exemplo, seu TextBox conteúdo é atualizado com alterações na origem da associação) se a origem da Associação fornecer as notificações adequadas.As indicated by the arrow in the previous figure, the data flow of a binding can go from the binding target to the binding source (for example, the source value changes when a user edits the value of a TextBox) and/or from the binding source to the binding target (for example, your TextBox content is updated with changes in the binding source) if the binding source provides the proper notifications.

Talvez você queira que seu aplicativo permita que os usuários alterem os dados e os propaguem de volta para o objeto de origem.You may want your app to enable users to change the data and propagate it back to the source object. Ou talvez você não queira permitir que os usuários atualizem os dados de origem.Or you may not want to enable users to update the source data. Você pode controlar o fluxo de dados definindo o Binding.Mode .You can control the flow of data by setting the Binding.Mode.

Esta figura ilustra os diferentes tipos de fluxo de dados:This figure illustrates the different types of data flow:

Fluxo de dados de vinculação de dadosData binding data flow

  • OneWaya associação faz com que as alterações na propriedade de origem atualizem automaticamente a propriedade de destino, mas as alterações na propriedade de destino não são propagadas de volta para a propriedade de origem.OneWay binding causes changes to the source property to automatically update the target property, but changes to the target property are not propagated back to the source property. Esse tipo de associação será apropriado se o controle associado for somente leitura de forma implícita.This type of binding is appropriate if the control being bound is implicitly read-only. Por exemplo, você pode associar a uma fonte, como uma cotação de ações, ou talvez a sua propriedade de destino não tenha nenhuma interface de controle fornecida para fazer alterações, como uma cor de plano de fundo associada a dados de uma tabela.For instance, you may bind to a source such as a stock ticker, or perhaps your target property has no control interface provided for making changes, such as a data-bound background color of a table. Se não houver necessidade de monitorar as alterações da propriedade de destino, o uso do modo de associação OneWay evitará a sobrecarga do modo de associação TwoWay.If there is no need to monitor the changes of the target property, using the OneWay binding mode avoids the overhead of the TwoWay binding mode.

  • TwoWaya associação faz com que as alterações sejam feitas na propriedade Source ou na propriedade de destino para atualizar automaticamente a outra.TwoWay binding causes changes to either the source property or the target property to automatically update the other. Esse tipo de associação é apropriado para formulários editáveis ou outros cenários de interface do usuário totalmente interativas.This type of binding is appropriate for editable forms or other fully interactive UI scenarios. A maioria das propriedades assume a associação como padrão OneWay , mas algumas propriedades de dependência (normalmente Propriedades de controles editáveis pelo usuário, como a TextBox.Text caixa de seleção e. ischeckd default para TwoWay Binding.Most properties default to OneWay binding, but some dependency properties (typically properties of user-editable controls such as the TextBox.Text and CheckBox.IsChecked default to TwoWay binding. Uma maneira programática de determinar se uma propriedade de dependência associa uma ou duas vias por padrão é obter os metadados de propriedade com DependencyProperty.GetMetadata e, em seguida, verificar o valor booliano da FrameworkPropertyMetadata.BindsTwoWayByDefault propriedade.A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata with DependencyProperty.GetMetadata and then check the Boolean value of the FrameworkPropertyMetadata.BindsTwoWayByDefault property.

  • OneWayToSourceé o inverso da OneWay Associação; ele atualiza a propriedade Source quando a propriedade de destino é alterada.OneWayToSource is the reverse of OneWay binding; it updates the source property when the target property changes. Um cenário de exemplo é se você só precisa reavaliar o valor de origem da interface do usuário.One example scenario is if you only need to reevaluate the source value from the UI.

  • Não ilustrado na figura a OneTime associação, que faz com que a propriedade Source inicialize a propriedade de destino, mas não propaga as alterações subsequentes.Not illustrated in the figure is OneTime binding, which causes the source property to initialize the target property but does not propagate subsequent changes. Se o contexto de dados for alterado ou o objeto no contexto de dados for alterado, a alteração não será refletida na propriedade de destino.If the data context changes or the object in the data context changes, the change is not reflected in the target property. Esse tipo de associação será apropriado se um instantâneo do estado atual for apropriado ou se os dados forem verdadeiramente estáticos.This type of binding is appropriate if either a snapshot of the current state is appropriate or the data is truly static. Esse tipo de associação também é útil se você deseja inicializar a propriedade de destino com um valor de uma propriedade de origem e o contexto de dados não é conhecido com antecedência.This type of binding is also useful if you want to initialize your target property with some value from a source property and the data context is not known in advance. Esse modo é essencialmente uma forma mais simples de OneWay associação que fornece melhor desempenho em casos em que o valor de origem não é alterado.This mode is essentially a simpler form of OneWay binding that provides better performance in cases where the source value does not change.

Para detectar alterações de origem (aplicáveis OneWay às TwoWay associações e), a origem deve implementar um mecanismo de notificação de alteração de propriedade adequado, como INotifyPropertyChanged .To detect source changes (applicable to OneWay and TwoWay bindings), the source must implement a suitable property change notification mechanism such as INotifyPropertyChanged. Consulte como implementar a notificação de alteração de propriedade para obter um exemplo de uma INotifyPropertyChanged implementação.See How to: Implement property change notification for an example of an INotifyPropertyChanged implementation.

A Binding.Mode propriedade fornece mais informações sobre modos de associação e um exemplo de como especificar a direção de uma associação.The Binding.Mode property provides more information about binding modes and an example of how to specify the direction of a binding.

O que dispara as atualizações de origemWhat triggers source updates

Associações que são TwoWay ou OneWayToSource escutam alterações na propriedade de destino e as propagam de volta para a origem, conhecidas como atualização da origem.Bindings that are TwoWay or OneWayToSource listen for changes in the target property and propagate them back to the source, known as updating the source. Por exemplo, você pode editar o texto de uma caixa de texto para alterar o valor da origem subjacente.For example, you may edit the text of a TextBox to change the underlying source value.

No entanto, seu valor de origem é atualizado enquanto você está editando o texto ou depois de terminar de editar o texto e o controle perde o foco?However, is your source value updated while you are editing the text or after you finish editing the text and the control loses focus? A Binding.UpdateSourceTrigger propriedade determina o que dispara a atualização da origem.The Binding.UpdateSourceTrigger property determines what triggers the update of the source. Os pontos das setas à direita na figura a seguir ilustram a função da Binding.UpdateSourceTrigger propriedade.The dots of the right arrows in the following figure illustrate the role of the Binding.UpdateSourceTrigger property.

Diagrama que mostra a função da propriedade UpdateSourceTrigger.

Se o UpdateSourceTrigger valor for UpdateSourceTrigger.PropertyChanged , o valor apontado pela seta para a direita TwoWay ou pelas OneWayToSource associações será atualizado assim que a propriedade de destino for alterada.If the UpdateSourceTrigger value is UpdateSourceTrigger.PropertyChanged, then the value pointed to by the right arrow of TwoWay or the OneWayToSource bindings is updated as soon as the target property changes. No entanto, se o UpdateSourceTrigger valor for LostFocus , esse valor somente será atualizado com o novo valor quando a propriedade de destino perder o foco.However, if the UpdateSourceTrigger value is LostFocus, then that value only is updated with the new value when the target property loses focus.

Semelhante à Mode propriedade, diferentes propriedades de dependência têm valores padrão diferentes UpdateSourceTrigger .Similar to the Mode property, different dependency properties have different default UpdateSourceTrigger values. 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.The default value for most dependency properties is PropertyChanged, while the TextBox.Text property has a default value of LostFocus. PropertyChangedsignifica que as atualizações de origem geralmente ocorrem sempre que a propriedade de destino é alterada.PropertyChanged means the source updates usually happen whenever the target property changes. Alterações instantâneas são bem para caixas de seleção e outros controles simples.Instant changes are fine for CheckBoxes and other simple controls. No entanto, para campos de texto, a atualização após cada pressionamento de tecla pode diminuir o desempenho e nega ao usuário a oportunidade usual de Backspace e corrigir erros de digitação antes de confirmar o novo valor.However, for text fields, updating after every keystroke can diminish performance and denies the user the usual opportunity to backspace and fix typing errors before committing to the new value.

Consulte a UpdateSourceTrigger página de propriedades para obter informações sobre como localizar o valor padrão de uma propriedade de dependência.See the UpdateSourceTrigger property page for information about how to find the default value of a dependency property.

A tabela a seguir fornece um cenário de exemplo para cada UpdateSourceTrigger valor usando o TextBox como um exemplo.The following table provides an example scenario for each UpdateSourceTrigger value using the TextBox as an example.

Valor de UpdateSourceTriggerUpdateSourceTrigger value Quando o valor de origem é atualizadoWhen the source value is updated Cenário de exemplo para TextBoxExample scenario for TextBox
LostFocus(padrão para TextBox.Text )LostFocus (default for TextBox.Text) Quando o controle TextBox perde o foco.When the TextBox control loses focus. Uma caixa de texto associada à lógica de validação (consulte a validação de dados abaixo).A TextBox that is associated with validation logic (see Data Validation below).
PropertyChanged Conforme você digita no TextBox .As you type into the TextBox. Controles de caixa de texto em uma janela de sala de chat.TextBox controls in a chat room window.
Explicit Quando o aplicativo chama UpdateSource .When the app calls UpdateSource. Os controles de caixa de texto em um formulário editável (atualiza os valores de origem somente quando o usuário clica no botão enviar).TextBox controls in an editable form (updates the source values only when the user clicks the submit button).

Para obter um exemplo, consulte como controlar quando o texto de TextBox atualiza a origem.For an example, see How to: Control when the TextBox text updates the source.

Criando uma associaçãoCreating a binding

Para redefinir alguns dos conceitos discutidos nas seções anteriores, você estabelece uma associação usando o Binding objeto e cada associação geralmente tem quatro componentes: um destino de associação, uma propriedade de destino, uma fonte de associação e um caminho para o valor de origem a ser usado.To restate some of the concepts discussed in the previous sections, you establish a binding using the Binding object, and each binding usually has four components: a binding target, a target property, a binding source, and a path to the source value to use. Esta seção discute como configurar uma associação.This section discusses how to set up a binding.

Considere o exemplo a seguir, no qual o objeto de origem da associação é uma classe chamada MyData que é definida no namespace SDKSample.Consider the following example, in which the binding source object is a class named MyData that is defined in the SDKSample namespace. Para fins de demonstração, MyData tem uma propriedade de cadeia de caracteres chamada colorname cujo valor é definido como "Red".For demonstration purposes, MyData has a string property named ColorName whose value is set to "Red". Assim, esse exemplo gera um botão com uma tela de fundo vermelha.Thus, this example generates a button with a red background.

<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://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 obter mais informações sobre a sintaxe de declaração de associação e exemplos de como configurar uma associação no código, consulte visão geral de declarações de associação.For more information on the binding declaration syntax and examples of how to set up a binding in code, see Binding Declarations Overview.

Se nós aplicarmos esse exemplo a nosso diagrama básico, a figura resultante será semelhante à exibida a seguir.If we apply this example to our basic diagram, the resulting figure looks like the following. Esta figura descreve uma OneWay Associação porque a propriedade Background dá suporte à OneWay associação por padrão.This figure describes a OneWay binding because the Background property supports OneWay binding by default.

Diagrama que mostra a propriedade de plano de fundo de ligação de dados.

Você pode imaginar por que essa associação funciona, embora a propriedade colorname seja do tipo cadeia de caracteres enquanto a Background propriedade for do tipo Brush .You may wonder why this binding works even though the ColorName property is of type string while the Background property is of type Brush. Essa associação usa a conversão de tipo padrão, que é discutida na seção de conversão de dados .This binding uses default type conversion, which is discussed in the Data conversion section.

Especificando a origem da AssociaçãoSpecifying the binding source

Observe que, no exemplo anterior, a origem da associação é especificada definindo a propriedade DockPanel. DataContext .Notice that in the previous example, the binding source is specified by setting the DockPanel.DataContext property. ButtonEm seguida, o herda o DataContext valor de DockPanel , que é seu elemento pai.The Button then inherits the DataContext value from the DockPanel, which is its parent element. Para reiterar, o objeto de origem da associação é um dos quatro componentes necessários de uma associação.To reiterate, the binding source object is one of the four necessary components of a binding. Portanto, sem o objeto de origem de associação que está sendo especificado, a associação não faria nada.Therefore, without the binding source object being specified, the binding would do nothing.

Há várias maneiras para especificar o objeto de origem de associação.There are several ways to specify the binding source object. O uso da DataContext propriedade em um elemento pai é útil quando você está associando várias propriedades à mesma fonte.Using the DataContext property on a parent element is useful when you are binding multiple properties to the same source. No entanto, às vezes pode ser mais apropriado especificar a origem da associação em declarações de associação individuais.However, sometimes it may be more appropriate to specify the binding source on individual binding declarations. Para o exemplo anterior, em vez de usar a DataContext propriedade, você pode especificar a origem da Associação definindo a Binding.Source propriedade diretamente na declaração de associação do botão, como no exemplo a seguir.For the previous example, instead of using the DataContext property, you can specify the binding source by setting the Binding.Source property directly on the binding declaration of the button, as in the following example.

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

Além de definir a DataContext propriedade em um elemento diretamente, herdar o DataContext valor de um ancestral (como o botão no primeiro exemplo) e especificar explicitamente a origem da associação, definindo a Binding.Source Propriedade na associação (como o botão último exemplo), você também pode usar a Binding.ElementName propriedade ou a Binding.RelativeSource propriedade para especificar a origem da associação.Other than setting the DataContext property on an element directly, inheriting the DataContext value from an ancestor (such as the button in the first example), and explicitly specifying the binding source by setting the Binding.Source property on the binding (such as the button the last example), you can also use the Binding.ElementName property or the Binding.RelativeSource property to specify the binding source. A ElementName propriedade é útil quando você está ligando a outros elementos em seu aplicativo, como quando você está usando um controle deslizante para ajustar a largura de um botão.The ElementName property is useful when you are binding to other elements in your app, such as when you are using a slider to adjust the width of a button. A RelativeSource propriedade é útil quando a associação é especificada em um ControlTemplate ou um Style .The RelativeSource property is useful when the binding is specified in a ControlTemplate or a Style. Para obter mais informações, consulte como especificar a origem da Associação.For more information, see How to: Specify the binding source.

Especificando o caminho para o valorSpecifying the path to the value

Se sua fonte de associação for um objeto, você usará a Binding.Path propriedade para especificar o valor a ser usado para sua associação.If your binding source is an object, you use the Binding.Path property to specify the value to use for your binding. Se você estiver ligando a dados XML, use a Binding.XPath propriedade para especificar o valor.If you are binding to XML data, you use the Binding.XPath property to specify the value. Em alguns casos, pode ser aplicável usar a Path Propriedade mesmo quando seus dados são XML.In some cases, it may be applicable to use the Path property even when your data is XML. Por exemplo, se você quiser acessar a propriedade Name de um XmlNode retornado (como resultado de uma consulta XPath), deverá usar a Path Propriedade além da XPath propriedade.For example, if you want to access the Name property of a returned XmlNode (as a result of an XPath query), you should use the Path property in addition to the XPath property.

Para obter mais informações, consulte Path as XPath Propriedades e.For more information, see the Path and XPath properties.

Embora tenhamos enfatizado que o Path para o valor a ser usado é um dos quatro componentes necessários de uma associação, nos cenários que você deseja associar a um objeto inteiro, o valor a ser usado seria o mesmo que o objeto de origem da associação.Although we have emphasized that the Path to the value to use is one of the four necessary components of a binding, in the scenarios that you want to bind to an entire object, the value to use would be the same as the binding source object. Nesses casos, é aplicável não especificar um Path .In those cases, it is applicable to not specify a Path. Considere o exemplo a seguir.Consider the following example.

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

O exemplo acima usa a sintaxe de associação vazia: {Binding}.The above example uses the empty binding syntax: {Binding}. Nesse caso, o ListBox herda o DataContext de um elemento DockPanel pai (não mostrado neste exemplo).In this case, the ListBox inherits the DataContext from a parent DockPanel element (not shown in this example). Quando o caminho não é especificado, o padrão é associar ao objeto inteiro.When the path is not specified, the default is to bind to the entire object. Em outras palavras, neste exemplo, o caminho saiu porque estamos associando a ItemsSource propriedade ao objeto inteiro.In other words, in this example, the path has been left out because we are binding the ItemsSource property to the entire object. (Consulte a seção associação às coleções para uma discussão aprofundada.)(See the Binding to collections section for an in-depth discussion.)

Além de ao associar a uma coleção, este cenário também é útil quando você deseja associar a um objeto inteiro em vez de apenas uma única propriedade de um objeto.Other than binding to a collection, this scenario is also useful when you want to bind to an entire object instead of just a single property of an object. Por exemplo, se o objeto de origem for do tipo String , talvez você queira simplesmente associar à própria cadeia de caracteres.For example, if your source object is of type String, you may simply want to bind to the string itself. Outro cenário comum é quando você deseja associar um elemento a um objeto com várias propriedades.Another common scenario is when you want to bind an element to an object with several properties.

Talvez seja necessário aplicar a lógica personalizada para que os dados sejam significativos para a propriedade de destino associada.You may need to apply custom logic so that the data is meaningful to your bound target property. A lógica personalizada pode estar na forma de um conversor personalizado se a conversão de tipo padrão não existir.The custom logic may be in the form of a custom converter if default type conversion does not exist. Consulte conversão de dados para obter informações sobre conversores.See Data conversion for information about converters.

Associação e BindingExpressionBinding and BindingExpression

Antes de entrar em outros recursos e usos da vinculação de dados, é útil introduzir a BindingExpression classe.Before getting into other features and usages of data binding, it is useful to introduce the BindingExpression class. Como você viu nas seções anteriores, a Binding classe é a classe de alto nível para a declaração de uma associação; ela fornece muitas propriedades que permitem que você especifique as características de uma associação.As you have seen in previous sections, the Binding class is the high-level class for the declaration of a binding; it provides many properties that allow you to specify the characteristics of a binding. Uma classe relacionada, BindingExpression , é o objeto subjacente que mantém a conexão entre a origem e o destino.A related class, BindingExpression, is the underlying object that maintains the connection between the source and the target. Uma associação contém todas as informações que podem ser compartilhadas entre várias expressões de associação.A binding contains all the information that can be shared across several binding expressions. Um BindingExpression é uma expressão de instância que não pode ser compartilhada e contém todas as informações de instância do Binding .A BindingExpression is an instance expression that cannot be shared and contains all the instance information of the Binding.

Considere o exemplo a seguir, em que myDataObject é uma instância da MyData classe, myBinding é o Binding objeto de origem e MyData é uma classe definida que contém uma propriedade de cadeia de caracteres denominada MyDataProperty .Consider the following example, where myDataObject is an instance of the MyData class, myBinding is the source Binding object, and MyData is a defined class that contains a string property named MyDataProperty. Este exemplo associa o conteúdo de texto de myText , uma instância do TextBlock , ao MyDataProperty .This example binds the text content of myText, an instance of TextBlock, to MyDataProperty.

// Make a new source
var myDataObject = new MyData();
var myBinding = new Binding("ColorName")
{
    Source = myDataObject
};

// Bind the data source to the TextBox control's Text dependency property
myText.SetBinding(TextBlock.TextProperty, myBinding);
' Make a New source
Dim myDataObject As New MyData
Dim myBinding As New Binding("ColorName")
myBinding.Source = myDataObject

' Bind the data source to the TextBox control's Text dependency property
myText.SetBinding(TextBlock.TextProperty, myBinding)

Você pode usar o mesmo objeto myBinding para criar outras associações.You can use the same myBinding object to create other bindings. Por exemplo, você pode usar o objeto Myassociation para associar o conteúdo de texto de uma caixa de seleção a MyDataProperty.For example, you can use the myBinding object to bind the text content of a check box to MyDataProperty. Nesse cenário, haverá duas instâncias de BindingExpression compartilhamento do objeto myBinding .In that scenario, there will be two instances of BindingExpression sharing the myBinding object.

Um BindingExpression objeto é retornado chamando GetBindingExpression -se em um objeto associado a dados.A BindingExpression object is returned by calling GetBindingExpression on a data-bound object. Os artigos a seguir demonstram alguns dos usos da BindingExpression classe:The following articles demonstrate some of the usages of the BindingExpression class:

Conversão de dadosData conversion

Na seção criando uma associação , o botão é vermelho porque sua Background propriedade está associada a uma propriedade de cadeia de caracteres com o valor "vermelho".In the Creating a binding section, the button is red because its Background property is bound to a string property with the value "Red". Esse valor de cadeia de caracteres funciona porque um conversor de tipo está presente no Brush tipo para converter o valor da cadeia de caracteres em um Brush .This string value works because a type converter is present on the Brush type to convert the string value to a Brush.

A adição dessas informações à figura na seção criando uma associação é parecida com esta.Adding this information to the figure in the Creating a Binding section looks like this.

Diagrama que mostra a propriedade padrão de associação de dados.

No entanto, e se, em vez de ter uma propriedade do tipo String, seu objeto de origem de associação tiver uma propriedade Color do tipo Color ?However, what if instead of having a property of type string your binding source object has a Color property of type Color? Nesse caso, para que a ligação funcione, você precisaria primeiro transformar o valor da propriedade Color em algo que a Background Propriedade aceite.In that case, in order for the binding to work you would need to first turn the Color property value into something that the Background property accepts. Você precisaria criar um conversor personalizado implementando a IValueConverter interface, como no exemplo a seguir.You would need to create a custom converter by implementing the IValueConverter interface, as in the following example.

[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;
    }
}
<ValueConversion(GetType(Color), GetType(SolidColorBrush))>
Public Class ColorBrushConverter
    Implements IValueConverter
    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
        Dim color As Color = CType(value, Color)
        Return New SolidColorBrush(color)
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
        Return Nothing
    End Function
End Class

Consulte IValueConverter para obter mais informações.See IValueConverter for more information.

Agora, o conversor personalizado é usado em vez da conversão padrão, e nosso diagrama é semelhante a este.Now the custom converter is used instead of default conversion, and our diagram looks like this.

Diagrama que mostra o conversor personalizado de vinculação de dados.

Para reiterar, conversões padrão podem estar disponíveis devido a conversores de tipo presentes no tipo para o qual a associação está sendo realizada.To reiterate, default conversions may be available because of type converters that are present in the type being bound to. Esse comportamento dependerá de quais conversores de tipo estão disponíveis no destino.This behavior will depend on which type converters are available in the target. Em caso de dúvida, crie seu próprio conversor.If in doubt, create your own converter.

A seguir estão alguns cenários típicos em que faz sentido implementar um conversor de dados:The following are some typical scenarios where it makes sense to implement a data converter:

  • Os dados devem ser exibidos de forma diferente, dependendo da cultura.Your data should be displayed differently, depending on culture. Por exemplo, talvez você queira implementar um conversor de moeda ou um conversor de data/hora do calendário com base nas convenções usadas em uma cultura específica.For instance, you might want to implement a currency converter or a calendar date/time converter based on the conventions used in a particular culture.

  • Os dados que está sendo usados não são necessariamente destinados a alterar o valor de texto de uma propriedade, mas sim destinados a alterar alguns outros valores como a origem de uma imagem ou então a cor ou o estilo do texto.The data being used is not necessarily intended to change the text value of a property, but is instead intended to change some other value, such as the source for an image, or the color or style of the display text. Conversores podem ser usados nesta instância convertendo a associação de uma propriedade que pode não parecer apropriada, assim como a associação de um campo de texto à propriedade Background de uma célula de tabela.Converters can be used in this instance by converting the binding of a property that might not seem to be appropriate, such as binding a text field to the Background property of a table cell.

  • Mais de um controle ou várias propriedades de controles são associados aos mesmos dados.More than one control or multiple properties of controls are bound to the same data. Nesse caso, a associação primária pode simplesmente exibir o texto, enquanto outras associações lidam com questões específicas de exibição, mas ainda usam a mesma associação como informações da origem.In this case, the primary binding might just display the text, whereas other bindings handle specific display issues but still use the same binding as source information.

  • Uma propriedade de destino tem uma coleção de associações, que é chamada MultiBinding .A target property has a collection of bindings, which is termed MultiBinding. Para o MultiBinding , você usa um personalizado IMultiValueConverter para produzir um valor final dos valores das associações.For MultiBinding, you use a custom IMultiValueConverter to produce a final value from the values of the bindings. Por exemplo, a cor pode ser computada de valores vermelhos, azuis e verdes, que podem ser valores dos mesmos ou de diferentes objetos de origem da associação.For example, color may be computed from red, blue, and green values, which can be values from the same or different binding source objects. Consulte MultiBinding para obter exemplos e informações.See MultiBinding for examples and information.

Associando a coleçõesBinding to collections

Um objeto de origem de associação pode ser tratado como um único objeto cujas propriedades contêm dados ou como uma coleção de dados de objetos polimórficos que geralmente são agrupados juntos (como o resultado de uma consulta a um banco de dado).A binding source object can be treated either as a single object whose properties contain data or as a data collection of polymorphic objects that are often grouped together (such as the result of a query to a database). Até agora, discutimos apenas a ligação a objetos individuais.So far we've only discussed binding to single objects. No entanto, a associação a uma coleção de dados é um cenário comum.However, binding to a data collection is a common scenario. Por exemplo, um cenário comum é usar um ItemsControl ListBox , ListView ou TreeView para exibir uma coleção de dados, como no aplicativo mostrado na seção o que é Associação de dados .For example, a common scenario is to use an ItemsControl such as a ListBox, ListView, or TreeView to display a data collection, such as in the app shown in the What is data binding section.

Felizmente, nosso diagrama básico ainda se aplica.Fortunately, our basic diagram still applies. Se você estiver associando um ItemsControl a uma coleção, o diagrama terá esta aparência.If you are binding an ItemsControl to a collection, the diagram looks like this.

Diagrama que mostra o objeto ItemsControl de vinculação de dados.

Conforme mostrado neste diagrama, para associar um ItemsControl a um objeto de coleção, ItemsControl.ItemsSource a propriedade é a propriedade a ser usada.As shown in this diagram, to bind an ItemsControl to a collection object, ItemsControl.ItemsSource property is the property to use. Você pode considerar ItemsSource como o conteúdo do ItemsControl .You can think of ItemsSource as the content of the ItemsControl. A associação é OneWay porque a ItemsSource Propriedade dá suporte à OneWay associação por padrão.The binding is OneWay because the ItemsSource property supports OneWay binding by default.

Como implementar coleçõesHow to implement collections

Você pode enumerar em qualquer coleção que implemente a IEnumerable interface.You can enumerate over any collection that implements the IEnumerable interface. No entanto, para configurar associações dinâmicas para que as inserções ou exclusões na coleção atualizem a interface do usuário automaticamente, a coleção deve implementar a INotifyCollectionChanged interface.However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. Essa interface expõe um evento que deve ser acionado sempre que a coleção subjacente for alterada.This interface exposes an event that should be raised whenever the underlying collection changes.

O WPF fornece a ObservableCollection<T> classe, que é uma implementação interna de uma coleção de dados que expõe a INotifyCollectionChanged interface.WPF provides the ObservableCollection<T> class, which is a built-in implementation of a data collection that exposes the INotifyCollectionChanged interface. Para oferecer suporte total à transferência de valores de dados de objetos de origem para destinos, cada objeto em sua coleção que dá suporte a propriedades vinculáveis também deve implementar a INotifyPropertyChanged interface.To fully support transferring data values from source objects to targets, each object in your collection that supports bindable properties must also implement the INotifyPropertyChanged interface. Para obter mais informações, consulte visão geral de fontes de associação.For more information, see Binding sources overview.

Antes de implementar sua própria coleção, considere usar ObservableCollection<T> ou uma das classes de coleção existentes, como List<T> , Collection<T> e BindingList<T> , entre muitas outras.Before implementing your own collection, consider using ObservableCollection<T> or one of the existing collection classes, such as List<T>, Collection<T>, and BindingList<T>, among many others. Se você tiver um cenário avançado e quiser implementar sua própria coleção, considere usar o IList , que fornece uma coleção não genérica de objetos que podem ser acessados individualmente pelo índice e, portanto, fornece o melhor desempenho.If you have an advanced scenario and want to implement your own collection, consider using IList, which provides a non-generic collection of objects that can be individually accessed by the index, and thus provides the best performance.

Exibições de coleçãoCollection views

Quando o ItemsControl estiver associado a uma coleção de dados, talvez você queira classificar, filtrar ou agrupar os dados.Once your ItemsControl is bound to a data collection, you may want to sort, filter, or group the data. Para fazer isso, você usa exibições de coleção, que são classes que implementam a ICollectionView interface.To do that, you use collection views, which are classes that implement the ICollectionView interface.

O que são exibições de coleção?What Are collection views?

Uma exibição de coleção é uma camada sobre uma coleção de origem da associação que permite a você navegar e exibir a coleção de origem com base em consultas de classificação, filtragem e agrupamento, sem precisar alterar a coleção de origem subjacente.A collection view is a layer on top of a binding source collection that allows you to navigate and display the source collection based on sort, filter, and group queries, without having to change the underlying source collection itself. Uma exibição de coleção também mantém um ponteiro para o item atual na coleção.A collection view also maintains a pointer to the current item in the collection. Se a coleção de origem implementar a INotifyCollectionChanged interface, as alterações geradas pelo CollectionChanged evento serão propagadas para as exibições.If the source collection implements the INotifyCollectionChanged interface, the changes raised by the CollectionChanged event are propagated to the views.

Já que as exibições não alteram as coleções de origem subjacentes, cada coleção de origem pode ter várias exibições associadas a ela.Because views do not change the underlying source collections, each source collection can have multiple views associated with it. Por exemplo, você pode ter uma coleção de objetos Task.For example, you may have a collection of Task objects. Com o uso de exibições, você pode exibir esses mesmos dados de maneiras diferentes.With the use of views, you can display that same data in different ways. Por exemplo, no lado esquerdo da página, talvez você queira mostrar as tarefas ordenadas por prioridade e, no lado direito, agrupadas por área.For example, on the left side of your page you may want to show tasks sorted by priority, and on the right side, grouped by area.

Como criar uma exibiçãoHow to create a view

Uma maneira de criar e usar uma exibição é instanciar o objeto de exibição diretamente e então usá-lo como a origem da associação.One way to create and use a view is to instantiate the view object directly and then use it as the binding source. Por exemplo, considere o aplicativo de demonstração de vinculação de dados mostrado na seção o que é Associação de dados .For example, consider the Data binding demo app shown in the What is data binding section. O aplicativo é implementado de modo que o seja ListBox associado a uma exibição sobre a coleta de dados em vez da coleta de dados diretamente.The app is implemented such that the ListBox binds to a view over the data collection instead of the data collection directly. O exemplo a seguir é extraído do aplicativo de demonstração de vinculação de dados .The following example is extracted from the Data binding demo app. A CollectionViewSource classe é o proxy XAML de uma classe herdada de CollectionView .The CollectionViewSource class is the XAML proxy of a class that inherits from CollectionView. Neste exemplo específico, o Source da exibição está associado à coleção AuctionItems (do tipo ObservableCollection<T> ) do objeto de aplicativo atual.In this particular example, the Source of the view is bound to the AuctionItems collection (of type ObservableCollection<T>) of the current app object.

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

O recurso listingDataView , em seguida, serve como a fonte de associação para elementos no aplicativo, como o ListBox .The resource listingDataView then serves as the binding source for elements in the app, such as the ListBox.

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

Para criar outra exibição para a mesma coleção, você pode criar outra CollectionViewSource instância e dar a ela um x:Key nome diferente.To create another view for the same collection, you can create another CollectionViewSource instance and give it a different x:Key name.

A tabela a seguir mostra quais tipos de dados de exibição são criados como a exibição de coleção padrão ou CollectionViewSource com base no tipo de coleção de origem.The following table shows what view data types are created as the default collection view or by CollectionViewSource based on the source collection type.

Tipo de coleção de origemSource collection type Tipo de exibição de coleçãoCollection view type ObservaçõesNotes
IEnumerable Um tipo interno baseado emCollectionViewAn internal type based on CollectionView Não é possível agrupar itens.Cannot group items.
IList ListCollectionView Mais rápido.Fastest.
IBindingList BindingListCollectionView

Usando uma exibição padrãoUsing a default view

Especificar uma exibição de coleção como uma origem da associação é uma maneira de criar e usar uma exibição de coleção.Specifying a collection view as a binding source is one way to create and use a collection view. O WPF também cria uma exibição de coleção padrão para cada coleção usada como uma origem da associação.WPF also creates a default collection view for every collection used as a binding source. Se você associar diretamente a uma coleção, o WPF será associado à sua exibição padrão.If you bind directly to a collection, WPF binds to its default view. Essa exibição padrão é compartilhada por todas as associações para a mesma coleção, portanto, uma alteração feita em um modo de exibição padrão por um controle ou código associado (como classificação ou uma alteração no ponteiro do item atual, discutida posteriormente) é refletida em todas as outras associações para a mesma coleção.This default view is shared by all bindings to the same collection, so a change made to a default view by one bound control or code (such as sorting or a change to the current item pointer, discussed later) is reflected in all other bindings to the same collection.

Para obter a exibição padrão, use o GetDefaultView método.To get the default view, you use the GetDefaultView method. Para obter um exemplo, consulte obter a exibição padrão de uma coleção de dados.For an example, see Get the default view of a data collection.

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

Para melhorar o desempenho, as exibições de coleção para ADO.NET DataTable ou DataView objetos delegam classificação e filtragem para o DataView , que faz com que a classificação e a filtragem sejam compartilhadas entre todas as exibições de coleção da fonte de dados.To improve performance, collection views for ADO.NET DataTable or DataView objects delegate sorting and filtering to the DataView, which causes sorting and filtering to be shared across all collection views of the data source. Para habilitar cada exibição de coleção para classificar e filtrar de forma independente, inicialize cada modo de exibição de coleção com seu próprio DataView objeto.To enable each collection view to sort and filter independently, initialize each collection view with its own DataView object.

ClassificaçãoSorting

Conforme mencionado anteriormente, as exibições podem aplicar uma ordem de classificação para uma coleção.As mentioned before, views can apply a sort order to a collection. Já que eles existem na coleção subjacente, seus dados podem ter ou não uma ordem inerente e relevante.As it exists in the underlying collection, your data may or may not have a relevant, inherent order. A exibição da coleção permite impor uma ordem ou alterar a ordem padrão, com base em critérios de comparação fornecidos por você.The view over the collection allows you to impose an order, or change the default order, based on comparison criteria that you supply. Já que essa é uma exibição dos dados baseada no cliente, um cenário comum é que o usuário deseje classificar colunas de dados tabulares segundo o valor ao qual a coluna corresponde.Because it is a client-based view of the data, a common scenario is that the user might want to sort columns of tabular data per the value that the column corresponds to. Usando exibições, essa classificação controlada pelo usuário pode ser aplicada, novamente sem necessidade de alterações na coleção subjacente nem mesmo precisar repetir a consulta do conteúdo da coleção.Using views, this user-driven sort can be applied, again without making any changes to the underlying collection or even having to requery for the collection content. Para obter um exemplo, consulte classificar uma coluna GridView quando um cabeçalho é clicado.For an example, see Sort a GridView column when a header is clicked.

O exemplo a seguir mostra a lógica de classificação de "classificar por categoria e data" CheckBox da interface do usuário do aplicativo na seção o que é Associação de dados .The following example shows the sorting logic of the "Sort by category and date" CheckBox of the app UI in the What is data binding section.

private void AddSortCheckBox_Checked(object sender, RoutedEventArgs e)
{
    // Sort the items first by Category and then by StartDate
    listingDataView.SortDescriptions.Add(new SortDescription("Category", ListSortDirection.Ascending));
    listingDataView.SortDescriptions.Add(new SortDescription("StartDate", ListSortDirection.Ascending));
}
Private Sub AddSortCheckBox_Checked(sender As Object, e As RoutedEventArgs)
    ' Sort the items first by Category And then by StartDate
    listingDataView.SortDescriptions.Add(New SortDescription("Category", ListSortDirection.Ascending))
    listingDataView.SortDescriptions.Add(New SortDescription("StartDate", ListSortDirection.Ascending))
End Sub

FiltragemFiltering

As exibições também podem aplicar um filtro a uma coleção, de modo que a exibição mostre apenas um determinado subconjunto da coleção completa.Views can also apply a filter to a collection, so that the view shows only a certain subset of the full collection. Você pode filtrar por uma condição nos dados.You might filter on a condition in the data. Por exemplo, como é feito pelo aplicativo na seção o que é Associação de dados , o "mostrar apenas os dados" CheckBox contém a lógica para filtrar os itens que custam $25 ou mais.For instance, as is done by the app in the What is data binding section, the "Show only bargains" CheckBox contains logic to filter out items that cost $25 or more. O código a seguir é executado para definir ShowOnlyBargainsFilter como o Filter manipulador de eventos quando CheckBox selecionado.The following code is executed to set ShowOnlyBargainsFilter as the Filter event handler when that CheckBox is selected.

private void AddFilteringCheckBox_Checked(object sender, RoutedEventArgs e)
{
    if (((CheckBox)sender).IsChecked == true)
        listingDataView.Filter += ListingDataView_Filter;
    else
        listingDataView.Filter -= ListingDataView_Filter;
}
Private Sub AddFilteringCheckBox_Checked(sender As Object, e As RoutedEventArgs)
    Dim checkBox = DirectCast(sender, CheckBox)

    If checkBox.IsChecked = True Then
        AddHandler listingDataView.Filter, AddressOf ListingDataView_Filter
    Else
        RemoveHandler listingDataView.Filter, AddressOf ListingDataView_Filter
    End If
End Sub

O manipulador de eventos ShowOnlyBargainsFilter tem a implementação a seguir.The ShowOnlyBargainsFilter event handler has the following implementation.

private void ListingDataView_Filter(object sender, FilterEventArgs e)
{
    // Start with everything excluded
    e.Accepted = false;

    // Only inlcude items with a price less than 25
    if (e.Item is AuctionItem product && product.CurrentPrice < 25)
        e.Accepted = true;
}
Private Sub ListingDataView_Filter(sender As Object, e As FilterEventArgs)

    ' Start with everything excluded
    e.Accepted = False

    Dim product As AuctionItem = TryCast(e.Item, AuctionItem)

    If product IsNot Nothing Then

        ' Only include products with prices lower than 25
        If product.CurrentPrice < 25 Then e.Accepted = True

    End If

End Sub

Se você estiver usando uma das CollectionView classes diretamente em vez de CollectionViewSource , você usaria a Filter propriedade para especificar um retorno de chamada.If you are using one of the CollectionView classes directly instead of CollectionViewSource, you would use the Filter property to specify a callback. Para obter um exemplo, consulte Filtrar dados em uma exibição.For an example, see Filter Data in a View.

AgrupamentoGrouping

Exceto para a classe interna que exibe uma IEnumerable coleção, todas as exibições de coleção dão suporte ao agrupamento, o que permite ao usuário particionar a coleção no modo de exibição de coleção em grupos lógicos.Except for the internal class that views an IEnumerable collection, all collection views support grouping, which allows the user to partition the collection in the collection view into logical groups. Os grupos podem ser explícitos (caso em que o usuário fornece uma lista de grupos) ou então implícitos (caso em que os grupos são gerados dinamicamente, dependendo dos dados).The groups can be explicit, where the user supplies a list of groups, or implicit, where the groups are generated dynamically depending on the data.

O exemplo a seguir mostra a lógica do "Agrupar por categoria" CheckBox .The following example shows the logic of the "Group by category" CheckBox.

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

Para obter outro exemplo de agrupamento, consulte Agrupar itens em uma ListView que implementa uma GridView.For another grouping example, see Group Items in a ListView That Implements a GridView.

Ponteiros do item atualCurrent item pointers

As exibições também dão suporte à noção de um item atual.Views also support the notion of a current item. Você pode navegar pelos objetos em uma exibição de coleção.You can navigate through the objects in a collection view. Enquanto você navega, você está movendo um ponteiro de item que permite que você recupere o objeto existente nesse local específico na coleção.As you navigate, you are moving an item pointer that allows you to retrieve the object that exists at that particular location in the collection. Para obter um exemplo, consulte navegar pelos objetos em um CollectionView de dados.For an example, see Navigate through the objects in a data CollectionView.

Já que o WPF associa a uma coleção usando uma exibição (uma exibição que você especificar ou uma exibição padrão da coleção), todas as associações a coleções têm um ponteiro de item atual.Because WPF binds to a collection only by using a view (either a view you specify, or the collection's default view), all bindings to collections have a current item pointer. Ao associar a um modo de exibição, o caractere de barra ("/") em um valor Path atribui o item atual da exibição.When binding to a view, the slash ("/") character in a Path value designates the current item of the view. No exemplo a seguir, o contexto de dados é uma exibição de coleção.In the following example, the data context is a collection view. A primeira linha é associada à coleção.The first line binds to the collection. A segunda linha é associada ao item atual na coleção.The second line binds to the current item in the collection. A terceira linha é associada à propriedade Description do item atual na coleção.The third line binds to the Description property of the current item in the collection.

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

A sintaxe de barra e de propriedade também pode ser empilhada para transpor uma hierarquia de coleções.The slash and property syntax can also be stacked to traverse a hierarchy of collections. O exemplo a seguir associa o item atual de uma coleção chamada Offices, que é uma propriedade do item atual da coleção de origem.The following example binds to the current item of a collection named Offices, which is a property of the current item of the source collection.

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

O ponteiro do item atual pode ser afetado por qualquer classificação ou filtragem aplicada à coleção.The current item pointer can be affected by any sorting or filtering that is applied to the collection. A classificação preserva o ponteiro do item atual no último item selecionado, mas a exibição de coleção está agora reestruturada em torno dele.Sorting preserves the current item pointer on the last item selected, but the collection view is now restructured around it. (Talvez o item selecionado estivesse no início da lista antes, mas agora o item selecionado pode estar em algum lugar no meio.) A filtragem preserva o item selecionado se essa seleção permanecer no modo de exibição após a filtragem.(Perhaps the selected item was at the beginning of the list before, but now the selected item might be somewhere in the middle.) Filtering preserves the selected item if that selection remains in view after the filtering. Caso contrário, o ponteiro do item atual será definido como o primeiro item da exibição de coleção filtrada.Otherwise, the current item pointer is set to the first item of the filtered collection view.

Cenário de associação mestre-detalhesMaster-detail binding scenario

A noção de um item atual é útil não somente para navegação por itens em uma coleção, mas também para o cenário de associação mestre/detalhes.The notion of a current item is useful not only for navigation of items in a collection, but also for the master-detail binding scenario. Considere a interface do usuário do aplicativo na seção o que é Associação de dados novamente.Consider the app UI in the What is data binding section again. Nesse aplicativo, a seleção dentro de ListBox determina o conteúdo mostrado no ContentControl .In that app, the selection within the ListBox determines the content shown in the ContentControl. Para colocá-lo de outra maneira, quando um ListBox item é selecionado, o ContentControl mostra os detalhes do item selecionado.To put it in another way, when a ListBox item is selected, the ContentControl shows the details of the selected item.

Você pode implementar o cenário mestre/detalhes simplesmente associando dois ou mais controles à mesma exibição.You can implement the master-detail scenario simply by having two or more controls bound to the same view. O exemplo a seguir da demonstração de vinculação de dados mostra a marcação do ListBox e o ContentControl que você vê na interface do usuário do aplicativo na seção o que é Associação de dados .The following example from the Data binding demo shows the markup of the ListBox and the ContentControl you see on the app UI in the What is data binding section.

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

Observe que os dois controles estão associados à mesma origem, o recurso estático listingDataView (consulte a definição desse recurso na seção como criar uma exibição).Notice that both of the controls are bound to the same source, the listingDataView static resource (see the definition of this resource in the How to create a view section). Essa associação funciona porque, quando um objeto singleton ( ContentControl neste caso) está associado a uma exibição de coleção, ele automaticamente se vincula ao CurrentItem da exibição.This binding works because when a singleton object (the ContentControl in this case) is bound to a collection view, it automatically binds to the CurrentItem of the view. Os CollectionViewSource objetos sincronizam automaticamente a moeda e a seleção.The CollectionViewSource objects automatically synchronize currency and selection. Se o controle de lista não estiver associado a um CollectionViewSource objeto como neste exemplo, você precisará definir sua IsSynchronizedWithCurrentItem propriedade como para true que isso funcione.If your list control is not bound to a CollectionViewSource object as in this example, then you would need to set its IsSynchronizedWithCurrentItem property to true for this to work.

Para obter outros exemplos, consulte associar a uma coleção e exibir informações com base na seleção e usar o padrão de detalhes mestre com dados hierárquicos.For other examples, see Bind to a collection and display information based on selection and Use the master-detail pattern with hierarchical data.

Talvez você tenha observado que o exemplo anterior usa um modelo.You may have noticed that the above example uses a template. Na verdade, os dados não seriam exibidos da maneira que desejamos sem o uso de modelos (aquele usado explicitamente pelo ContentControl e aquele usado implicitamente pelo ListBox ).In fact, the data would not be displayed the way we wish without the use of templates (the one explicitly used by the ContentControl and the one implicitly used by the ListBox). Agora, na próxima seção, nos ocuparemos da modelagem de dados.We now turn to data templating in the next section.

Modelagem de dadosData templating

Sem o uso de modelos de dados, nossa interface do usuário do aplicativo na seção o que é Associação de dados seria semelhante ao seguinte.Without the use of data templates, our app UI in the What is data binding section would look like the following.

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

Conforme mostrado no exemplo na seção anterior, o ListBox controle e o ContentControl são vinculados a todo o objeto da coleção (ou mais especificamente, a exibição sobre o objeto de coleção) de s AuctionItem.As shown in the example in the previous section, both the ListBox control and the ContentControl are bound to the entire collection object (or more specifically, the view over the collection object) of AuctionItems. Sem instruções específicas de como exibir a coleta de dados, o ListBox exibe a representação de cadeia de caracteres de cada objeto na coleção subjacente e ContentControl exibe a representação de cadeia de caracteres do objeto ao qual está associado.Without specific instructions of how to display the data collection, the ListBox displays the string representation of each object in the underlying collection, and the ContentControl displays the string representation of the object it is bound to.

Para resolver esse problema, o aplicativo define DataTemplates .To solve that problem, the app defines DataTemplates. Conforme mostrado no exemplo na seção anterior, o ContentControl usa explicitamente o modelo de dados detailsProductListingTemplate .As shown in the example in the previous section, the ContentControl explicitly uses the detailsProductListingTemplate data template. O ListBox controle usa implicitamente o seguinte modelo de dados ao exibir os objetos AuctionItem na coleção.The ListBox control implicitly uses the following data template when displaying the AuctionItem objects in the collection.

<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 modelos de dados, a interface do usuário resultante é a mostrada na seção o que é a associação de dados .With the use of those two DataTemplates, the resulting UI is the one shown in the What is data binding section. Como você pode ver nessa captura de tela, além de permitir que você coloque dados em seus controles, os DataTemplates permitem que você defina visuais atraentes para seus dados.As you can see from that screenshot, in addition to letting you place data in your controls, DataTemplates allow you to define compelling visuals for your data. Por exemplo, DataTrigger s são usados no acima DataTemplate para que os s de AuctionItemcom o valor SpecialFeatures de realce sejam exibidos com uma borda laranja e uma estrela.For example, DataTriggers are used in the above DataTemplate so that AuctionItems with SpecialFeatures value of HighLight would be displayed with an orange border and a star.

Para obter mais informações sobre modelos de dados, consulte visão geral de modelagem de dados.For more information about data templates, see the Data templating overview.

Validação de dadosData validation

A maioria dos aplicativos que usam a entrada do usuário precisa ter lógica de validação para garantir que o usuário tenha inserido as informações esperadas.Most app that take user input need to have validation logic to ensure that the user has entered the expected information. As verificações de validação podem ser baseadas no tipo, no intervalo, no formato ou em outros requisitos específicos do aplicativo.The validation checks can be based on type, range, format, or other app-specific requirements. Esta seção discute como a validação de dados funciona no WPF.This section discusses how data validation works in WPF.

Associando regras de validação a uma associaçãoAssociating validation rules with a binding

O modelo de ligação de dados do WPF permite que você associe ValidationRules com o Binding objeto.The WPF data binding model allows you to associate ValidationRules with your Binding object. Por exemplo, o exemplo a seguir associa um TextBox a uma propriedade chamada StartPrice e adiciona um ExceptionValidationRule objeto à Binding.ValidationRules propriedade.For example, the following example binds a TextBox to a property named StartPrice and adds a ExceptionValidationRule object to the Binding.ValidationRules property.

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

Um ValidationRule objeto verifica se o valor de uma propriedade é válido.A ValidationRule object checks whether the value of a property is valid. O WPF tem dois tipos de objetos internos ValidationRule :WPF has two types of built-in ValidationRule objects:

Você também pode criar sua própria regra de validação derivando da ValidationRule classe e implementando o Validate método.You can also create your own validation rule by deriving from the ValidationRule class and implementing the Validate method. O exemplo a seguir mostra a regra usada pela seção "data de início" da listagem de produtos de adição TextBox . What is data bindingThe following example shows the rule used by the Add Product Listing "Start Date" TextBox from the What is data binding section.

public class FutureDateRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        // Test if date is valid
        if (DateTime.TryParse(value.ToString(), out DateTime date))
        {
            // Date is not in the future, fail
            if (DateTime.Now > date)
                return new ValidationResult(false, "Please enter a date in the future.");
        }
        else
        {
            // Date is not a valid date, fail
            return new ValidationResult(false, "Value is not a valid date.");
        }

        // Date is valid and in the future, pass
        return ValidationResult.ValidResult;
    }
}
Public Class FutureDateRule
    Inherits ValidationRule

    Public Overrides Function Validate(value As Object, cultureInfo As CultureInfo) As ValidationResult

        Dim inputDate As Date

        ' Test if date is valid
        If Date.TryParse(value.ToString, inputDate) Then

            ' Date is not in the future, fail
            If Date.Now > inputDate Then
                Return New ValidationResult(False, "Please enter a date in the future.")
            End If

        Else
            ' // Date Is Not a valid date, fail
            Return New ValidationResult(False, "Value is not a valid date.")
        End If

        ' Date is valid and in the future, pass
        Return ValidationResult.ValidResult

    End Function

End Class

O StartDateEntryForm TextBox usa esse FutureDateRule, conforme mostrado no exemplo a seguir.The StartDateEntryForm TextBox uses this FutureDateRule, as shown in the following example.

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

Como o UpdateSourceTrigger valor é PropertyChanged , o mecanismo de associação atualiza o valor de origem em cada pressionamento de tecla, o que significa que ele também verifica cada regra na ValidationRules coleção em cada pressionamento de tecla.Because the UpdateSourceTrigger value is PropertyChanged, the binding engine updates the source value on every keystroke, which means it also checks every rule in the ValidationRules collection on every keystroke. Discutiremos isso de modo mais aprofundado na seção Processo de validação.We discuss this further in the Validation Process section.

Fornecendo comentários visuaisProviding visual feedback

Se o usuário inserir um valor inválido, talvez você queira fornecer alguns comentários sobre o erro na interface do usuário do aplicativo.If the user enters an invalid value, you may want to provide some feedback about the error on the app UI. Uma maneira de fornecer esses comentários é definir a Validation.ErrorTemplate Propriedade anexada como um personalizado ControlTemplate .One way to provide such feedback is to set the Validation.ErrorTemplate attached property to a custom ControlTemplate. Conforme mostrado na subseção anterior, o StartDateEntryForm TextBox usa um ErrorTemplate chamado validationTemplate.As shown in the previous subsection, the StartDateEntryForm TextBox uses an ErrorTemplate called validationTemplate. O exemplo a seguir mostra a definição de validationTemplate.The following example shows the definition of validationTemplate.

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

O AdornedElementPlaceholder elemento especifica onde o controle que está sendo adornado deve ser colocado.The AdornedElementPlaceholder element specifies where the control being adorned should be placed.

Além disso, você também pode usar um ToolTip para exibir a mensagem de erro.In addition, you may also use a ToolTip to display the error message. O StartDateEntryForm e o StartPriceEntryForm TextBox es usam o estilo textStyleTextBox, que cria um ToolTip que exibe a mensagem de erro.Both the StartDateEntryForm and the StartPriceEntryFormTextBoxes use the style textStyleTextBox, which creates a ToolTip that displays the error message. O exemplo a seguir mostra a definição de textStyleTextBox.The following example shows the definition of textStyleTextBox. A propriedade anexada HasError é true quando uma ou mais das associações nas propriedades do elemento associado estão com erro.The attached property 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 personalizado ErrorTemplate e o ToolTip , o StartDateEntryForm é TextBox semelhante ao seguinte quando há um erro de validação.With the custom ErrorTemplate and the ToolTip, the StartDateEntryForm TextBox looks like the following when there is a validation error.

Erro de validação de associação de dadosData binding validation error

Se o Binding tiver regras de validação associadas, mas você não especificar um ErrorTemplate no controle ligado, um padrão ErrorTemplate será usado para notificar os usuários quando houver um erro de validação.If your Binding has associated validation rules but you do not specify an ErrorTemplate on the bound control, a default ErrorTemplate will be used to notify users when there is a validation error. O padrão ErrorTemplate é um modelo de controle que define uma borda vermelha na camada de adorno.The default ErrorTemplate is a control template that defines a red border in the adorner layer. Com o padrão ErrorTemplate e o ToolTip , a interface do usuário do StartPriceEntryForm é TextBox semelhante ao seguinte quando há um erro de validação.With the default ErrorTemplate and the ToolTip, the UI of the StartPriceEntryForm TextBox looks like the following when there is a validation error.

Erro de validação de associação de dadosData binding validation error

Para obter um exemplo de como fornecer lógica para validar todos os controles em uma caixa de diálogo, consulte a seção caixas de diálogo personalizadas na visão geral das caixas de diálogo.For an example of how to provide logic to validate all controls in a dialog box, see the Custom Dialog Boxes section in the Dialog boxes overview.

Processo de validaçãoValidation process

Geralmente, a validação ocorre quando o valor de um destino é transferido para a propriedade de origem da associação.Validation usually occurs when the value of a target is transferred to the binding source property. Essa transferência ocorre em TwoWay OneWayToSource associações e.This transfer occurs on TwoWay and OneWayToSource bindings. Para reiterar, o que causa uma atualização de origem depende do valor da UpdateSourceTrigger propriedade, conforme descrito na seção o que dispara as atualizações de origem .To reiterate, what causes a source update depends on the value of the UpdateSourceTrigger property, as described in the What triggers source updates section.

Os itens a seguir descrevem o processo de validação .The following items describe the validation process. Se um erro de validação ou outro tipo de erro ocorrer a qualquer momento durante esse processo, o processo será interrompido:If a validation error or other type of error occurs at any time during this process, the process is halted:

  1. O mecanismo de associação verifica se há objetos personalizados ValidationRule definidos cujo ValidationStep conjunto está definido como RawProposedValue para isso Binding ; nesse caso, ele chama o Validate método em cada ValidationRule um até que um deles seja executado em um erro ou até que todos eles passem.The binding engine checks if there are any custom ValidationRule objects defined whose ValidationStep is set to RawProposedValue for that Binding, in which case it calls the Validate method on each ValidationRule until one of them runs into an error or until all of them pass.

  2. O mecanismo de associação então chamará o conversor, se houver.The binding engine then calls the converter, if one exists.

  3. Se o conversor for bem-sucedido, o mecanismo de associação verificará se há algum ValidationRule objeto personalizado definido, cujo ValidationStep está definido como ConvertedProposedValue para isso Binding . nesse caso, ele chamará o Validate método em cada ValidationRule um que tenha ValidationStep definido como ConvertedProposedValue até que um deles tenha um erro ou até que todos eles passem.If the converter succeeds, the binding engine checks if there are any custom ValidationRule objects defined whose ValidationStep is set to ConvertedProposedValue for that Binding, in which case it calls the Validate method on each ValidationRule that has ValidationStep set to ConvertedProposedValue until one of them runs into an error or until all of them pass.

  4. O mecanismo de associação define a propriedade de origem.The binding engine sets the source property.

  5. O mecanismo de associação verifica se há objetos personalizados ValidationRule definidos cujo ValidationStep conjunto está definido como UpdatedValue para isso. Binding nesse caso, ele chama o Validate método em cada ValidationRule um que tenha ValidationStep definido como até que UpdatedValue um deles tenha um erro ou até que todos eles passem.The binding engine checks if there are any custom ValidationRule objects defined whose ValidationStep is set to UpdatedValue for that Binding, in which case it calls the Validate method on each ValidationRule that has ValidationStep set to UpdatedValue until one of them runs into an error or until all of them pass. Se um DataErrorValidationRule estiver associado a uma associação e seu ValidationStep estiver definido como o padrão, UpdatedValue o DataErrorValidationRule será verificado neste ponto.If a DataErrorValidationRule is associated with a binding and its ValidationStep is set to the default, UpdatedValue, the DataErrorValidationRule is checked at this point. Neste ponto, qualquer associação que tenha o ValidatesOnDataErrors conjunto definido como true está marcada.At this point any binding that has the ValidatesOnDataErrors set to true is checked.

  6. O mecanismo de associação verifica se há objetos personalizados ValidationRule definidos cujo ValidationStep conjunto está definido como CommittedValue para isso. Binding nesse caso, ele chama o Validate método em cada ValidationRule um que tenha ValidationStep definido como até que CommittedValue um deles tenha um erro ou até que todos eles passem.The binding engine checks if there are any custom ValidationRule objects defined whose ValidationStep is set to CommittedValue for that Binding, in which case it calls the Validate method on each ValidationRule that has ValidationStep set to CommittedValue until one of them runs into an error or until all of them pass.

Se um não ValidationRule passar algum tempo durante todo esse processo, o mecanismo de associação criará um ValidationError objeto e o adicionará à Errors coleção do elemento associado.If a ValidationRule does not pass at any time throughout this process, the binding engine creates a ValidationError object and adds it to the Errors collection of the bound element. Antes que o mecanismo de associação execute os ValidationRule objetos em qualquer etapa determinada, ele remove qualquer ValidationError que foi adicionado à Errors Propriedade anexada do elemento associado durante essa etapa.Before the binding engine runs the ValidationRule objects at any given step, it removes any ValidationError that was added to the Errors attached property of the bound element during that step. Por exemplo, se um ValidationRule cujo ValidationStep estiver definido como UpdatedValue falha, na próxima vez que o processo de validação ocorrer, o mecanismo de associação removerá isso ValidationError imediatamente antes de chamar qualquer um ValidationRule que tenha sido ValidationStep definido como UpdatedValue .For example, if a ValidationRule whose ValidationStep is set to UpdatedValue failed, the next time the validation process occurs, the binding engine removes that ValidationError immediately before it calls any ValidationRule that has ValidationStep set to UpdatedValue.

Quando Errors não está vazio, a HasError Propriedade anexada do elemento é definida como true .When Errors is not empty, the HasError attached property of the element is set to true. Além disso, se a NotifyOnValidationError propriedade de Binding for definida como true , o mecanismo de associação gerará o Validation.Error evento anexado no elemento.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.

Observe também que uma transferência de valor válida em qualquer direção (destino para origem ou origem para destino) limpa a Errors Propriedade anexada.Also note that a valid value transfer in either direction (target to source or source to target) clears the Errors attached property.

Se a associação tiver um ExceptionValidationRule associado a ela ou se a ValidatesOnExceptions propriedade estiver definida como true e uma exceção for lançada quando o mecanismo de associação definir a origem, o mecanismo de associação verificará se há um UpdateSourceExceptionFilter .If the binding either has an ExceptionValidationRule associated with it, or had the ValidatesOnExceptions property is set to true and an exception is thrown when the binding engine sets the source, the binding engine checks to see if there is a UpdateSourceExceptionFilter. Você tem a opção de usar o UpdateSourceExceptionFilter retorno de chamada para fornecer um manipulador personalizado para lidar com exceções.You have the option to use the UpdateSourceExceptionFilter callback to provide a custom handler for handling exceptions. Se um UpdateSourceExceptionFilter não for especificado no Binding , o mecanismo de associação criará um ValidationError com a exceção e o adicionará à Errors coleção do elemento associado.If an UpdateSourceExceptionFilter is not specified on the Binding, the binding engine creates a ValidationError with the exception and adds it to the Errors collection of the bound element.

Mecanismo de depuraçãoDebugging mechanism

Você pode definir a propriedade anexada TraceLevel em um objeto relacionado à associação para receber informações sobre o status de uma associação específica.You can set the attached property TraceLevel on a binding-related object to receive information about the status of a specific binding.

Veja tambémSee also