Panoramica sul data bindingData Binding Overview

Il data binding Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) rappresenta per le applicazioni un modo semplice e coerente di presentare i dati e di interagire con essi.Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) data binding provides a simple and consistent way for applications to present and interact with data. È possibile eseguire il data binding degli elementi a diverse origini dati sotto forma di oggetti Common Language Runtime (CLR)common language runtime (CLR) e XMLXML.Elements can be bound to data from a variety of data sources in the form of Common Language Runtime (CLR)common language runtime (CLR) objects and XMLXML. ContentControls, ad esempio Button e ItemsControls, ad esempio ListBox e ListView dispongono di funzionalità incorporate per abilitare lo stile flessibile dei singoli elementi di dati o raccolte di elementi di dati.ContentControls such as Button and ItemsControls such as ListBox and ListView have built-in functionality to enable flexible styling of single data items or collections of data items. In cima ai dati è possibile generare visualizzazioni di ordinamento, filtro e raggruppamento.Sort, filter, and group views can be generated on top of the data.

La funzionalità di data binding in WPFWPF presenta molti vantaggi rispetto ai modelli tradizionali, tra cui un'ampia gamma di proprietà che supportano implicitamente il data binding, una rappresentazione dei dati mediante Interfaccia utenteUI flessibile e una netta separazione tra logica di business e Interfaccia utenteUI.The data binding functionality in WPFWPF has several advantages over traditional models, including a broad range of properties that inherently support data binding, flexible Interfaccia utenteUI representation of data, and clean separation of business logic from Interfaccia utenteUI.

In questo argomento illustra prima di tutto i concetti fondamentali WPFWPF data binding e successivamente passa ad analizzare l'utilizzo del Binding classe e altre funzionalità di data binding.This topic first discusses concepts fundamental to WPFWPF data binding and then goes into the usage of the Binding class and other features of data binding.

Definizione di data bindingWhat Is Data Binding?

Il data binding è il processo tramite cui viene stabilita una connessione tra l'Interfaccia utenteUI dell'applicazione e la logica di business.Data binding is the process that establishes a connection between the application Interfaccia utenteUI and business logic. Se le impostazioni del binding sono corrette e i dati forniscono le notifiche appropriate, quando il valore dei dati viene modificato, gli elementi a essi associati riflettono automaticamente le modifiche apportate.If the binding has the correct settings and the data provides the proper notifications, then, when the data changes its value, the elements that are bound to the data reflect changes automatically. Il data binding prevede anche che, se una rappresentazione esterna dei dati in un elemento viene modificata, i dati sottostanti possono essere automaticamente aggiornati in modo da riflettere la modifica.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. Ad esempio, se l'utente modifica il valore in un TextBox elemento, il valore di dati sottostante viene aggiornata automaticamente per riflettere tale modifica.For example, if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.

Un utilizzo tipico del data binding consiste nell'inserimento di dati di configurazione locale o del server in moduli o in altri controlli Interfaccia utenteUI.A typical use of data binding is to place server or local configuration data into forms or other Interfaccia utenteUI controls. In WPFWPF questo concetto viene esteso per includere il binding di un'ampia gamma di proprietà a varie origini dati.In WPFWPF, this concept is expanded to include the binding of a broad range of properties to a variety of data sources. In WPFWPF le proprietà di dipendenza degli elementi possono essere associate a oggetti CLRCLR (inclusi gli oggetti ADO.NETADO.NET o gli oggetti associati a servizi Web e a proprietà Web) e a dati XMLXML.In WPFWPF, dependency properties of elements can be bound to CLRCLR objects (including ADO.NETADO.NET objects or objects associated with Web Services and Web properties) and XMLXML data.

Per un esempio di data binding, osservare l'Interfaccia utenteUI dell'applicazione seguente disponibile in Demo di data binding:For an example of data binding, take a look at the following application Interfaccia utenteUI from the Data Binding Demo:

Screenshot di esempio di data bindingData binding sample screen shot

La figura precedente mostra l'Interfaccia utenteUI di un'applicazione che visualizza un elenco di articoli da vendere all'asta.The above is the Interfaccia utenteUI of an application that displays a list of auction items. L'applicazione mostra le funzionalità di data binding seguenti:The application demonstrates the following features of data binding:

  • Il contenuto di ListBox è associato a una raccolta di AuctionItem oggetti.The content of the ListBox is bound to a collection of AuctionItem objects. Un oggetto AuctionItem dispone di diverse proprietà, tra cui Description, StartPrice, StartDate, Category, SpecialFeatures e così via.An AuctionItem object has properties such as Description, StartPrice, StartDate, Category, SpecialFeatures, etc.

  • I dati (AuctionItem oggetti) visualizzati nei ListBox è basato su modelli in modo che la descrizione e il prezzo corrente vengono visualizzati per ogni elemento.The data (AuctionItem objects) displayed in the ListBox is templated so that the description and the current price are shown for each item. Questa operazione viene eseguita usando un DataTemplate.This is done using a DataTemplate. L'aspetto di ogni articolo dipende inoltre dal valore di SpecialFeatures dell'oggetto AuctionItem visualizzato.In addition, the appearance of each item depends on the SpecialFeatures value of the AuctionItem being displayed. Se il valore di SpecialFeatures dell'oggetto AuctionItem è Color, l'articolo avrà un bordo blu.If the SpecialFeatures value of the AuctionItem is Color, the item has a blue border. Se il valore è Highlight, l'articolo sarà dotato di un bordo arancione e di una stella.If the value is Highlight, the item has an orange border and a star. La sezione Modelli di dati include informazioni sull'applicazione di modelli ai dati.The Data Templating section provides information about data templating.

  • L'utente può raggruppare, filtrare o ordinare i dati utilizzando il CheckBoxes fornito.The user can group, filter, or sort the data using the CheckBoxes provided. Nell'immagine precedente, "Group by category" e "Sort by category and date" CheckBoxsono stati selezionati.In the image above, the "Group by category" and "Sort by category and date" CheckBoxes are selected. I dati sono raggruppati in base alla categoria del prodotto e i nomi delle categorie seguono l'ordine alfabetico.You may have noticed that the data is grouped based on the category of the product, and the category name is in alphabetical order. Benché non risulti evidente dalla figura, gli articoli sono anche ordinati in base alla data di inizio all'interno di ogni categoria.It is difficult to notice from the image but the items are also sorted by the start date within each category. Questa operazione viene eseguita usando una visualizzazione di raccolta.This is done using a collection view. La sezione Binding alle raccolte descrive le visualizzazioni di raccolta.The Binding to Collections section discusses collection views.

  • Quando l'utente seleziona un elemento, il ContentControl vengono visualizzati i dettagli dell'elemento selezionato.When the user selects an item, the ContentControl displays the details of the selected item. Si parla in questo caso di scenario master-dettagli.This is called the Master-Detail scenario. La sezione Scenario master-dettagli include informazioni su questo tipo di scenario di binding.The Master-Detail Scenario section provides information about this type of binding scenario.

  • Il tipo dei StartDate è di proprietà DateTime, che restituisce una data che include l'ora fino al millisecondo.The type of the StartDate property is DateTime, which returns a date that includes the time to the millisecond. In questa applicazione è stato usato un convertitore personalizzato per visualizzare una stringa di data più breve.In this application, a custom converter has been used so that a shorter date string is displayed. La sezione Conversione dei dati include informazioni sui convertitori.The Data Conversion section provides information about converters.

Quando l'utente fa clic sul pulsante Add Product (Aggiungi prodotto), viene visualizzato il modulo seguente:When the user clicks the Add Product button, the following form comes up:

Pagina Add Product ListingAdd Product Listing page

L'utente può modificare i campi del modulo, visualizzare in anteprima il prodotto usando i riquadri di anteprima rapida e di anteprima più dettagliata e quindi fare clic su Submit (Inoltra) per aggiungere il nuovo prodotto.The user can edit the fields in the form, preview the product listing using the short preview and the more detailed preview panes, and then click submit to add the new product listing. Le funzionalità di raggruppamento, filtro e ordinamento esistenti verranno applicate alla nuova voce.Any existing grouping, filtering and sorting functionalities will apply to the new entry. In questo caso specifico, l'articolo immesso nella figura precedente verrà visualizzato come secondo articolo della categoria Computer.In this particular case, the item entered in the above image will be displayed as the second item within the Computer category.

Non visualizzato in questa immagine è la logica di convalida fornita nel data di inizio TextBox.Not shown in this image is the validation logic provided in the Start Date TextBox. Se l'utente immette un valore non valido date (formattazione non validi o una data già trascorsa), l'utente riceverà una notifica con un ToolTip e un punto esclamativo rosso accanto al 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. La sezione Convalida dei dati descrive come creare la logica di convalida.The Data Validation section discusses how to create validation logic.

Prima di approfondire le diverse funzionalità di data binding delineate finora, verranno trattati nella sezione successiva i concetti fondamentali necessari a comprendere il data binding WPFWPF.Before going into the different features of data binding outlined above, we will first discuss in the next section the fundamental concepts that are critical to understanding WPFWPF data binding.

Concetti di base sul data bindingBasic Data Binding Concepts

Indipendentemente dall'elemento che si intende associare e dalla natura dell'origine dati, ogni binding si basa sempre sul modello illustrato nella figura seguente: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:

Diagramma di data binding di baseBasic data binding diagram

Come illustrato nella figura precedente, il data binding funge essenzialmente da ponte tra la destinazione e l'origine del binding.As illustrated by the above figure, data binding is essentially the bridge between your binding target and your binding source. La figura illustra i concetti fondamentali seguenti relativi al data binding WPFWPF:The figure demonstrates the following fundamental WPFWPF data binding concepts:

  • Ogni binding possiede in genere quattro componenti: un oggetto di destinazione del binding, una proprietà di destinazione, un'origine del binding e un percorso al valore nell'origine del binding da usare.Typically, each binding has these four components: a binding target object, a target property, a binding source, and a path to the value in the binding source to use. Ad esempio, se si desidera associare il contenuto di un TextBox per il nome proprietà di un dipendente dell'oggetto, l'oggetto di destinazione è il TextBox, la proprietà di destinazione è il Text proprietà, è il valore da usare Name, e l'oggetto di origine è la dipendente oggetto.For example, if you want to bind the content of a TextBox to the Name property of an Employee object, 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.

  • La proprietà di destinazione deve essere una proprietà di dipendenza.The target property must be a dependency property. La maggior parte delle UIElement proprietà sono proprietà di dipendenza e la maggior parte delle proprietà di dipendenza, ad eccezione di quelli di sola lettura, supportano il data binding per impostazione predefinita.Most UIElement properties are dependency properties and most dependency properties, except read-only ones, support data binding by default. (Solo DependencyObject tipi possono definire le proprietà di dipendenza e tutti i UIElementderivano da DependencyObject.)(Only DependencyObject types can define dependency properties and all UIElements derive from DependencyObject.)

  • Sebbene non sia specificato nella figura, è importante notare che l'oggetto di origine del binding non è necessariamente costituito da un oggetto CLRCLR personalizzato.Although not specified in the figure, it should be noted that the binding source object is not restricted to being a custom CLRCLR object. Il data binding WPFWPF supporta dati nel formato di oggetti CLRCLR e XMLXML.WPFWPF data binding supports data in the form of CLRCLR objects and XMLXML. Per fornire alcuni esempi, l'origine del binding può essere un UIElement, qualsiasi oggetto elenco, una CLRCLR oggetto associato ADO.NETADO.NET dati o servizi Web o un oggetto XmlNode che contiene il XMLXML dati.To provide some examples, your binding source may be a UIElement, any list object, a CLRCLR object that is associated with ADO.NETADO.NET data or Web Services, or an XmlNode that contains your XMLXML data. Per altre informazioni, vedere Cenni preliminari sulle origini del binding.For more information, see Binding Sources Overview.

Come detto in altri argomenti concernenti Software Development Kit (SDK)software development kit (SDK), è importante ricordare che quando si stabilisce un binding, si associa una destinazione del binding a un'origine del binding.As you read through other Software Development Kit (SDK)software development kit (SDK) topics, it is important to remember that when you are establishing a binding, you are binding a binding target to a binding source. Ad esempio, se si visualizzano alcuni sottostante XMLXML i dati in un ListBox tramite data binding, si esegue il binding i ListBox per il XMLXML dati.For example, if you are displaying some underlying XMLXML data in a ListBox using data binding, you are binding your ListBox to the XMLXML data.

Per stabilire un'associazione, si utilizza il Binding oggetto.To establish a binding, you use the Binding object. Il resto di questo argomento vengono descritti molti dei concetti associati e alcune delle proprietà e l'utilizzo del Binding oggetto.The rest of this topic discusses many of the concepts associated with and some of the properties and usage of the Binding object.

Direzione del flusso di datiDirection of the Data Flow

Come indicato in precedenza e come indicato dalla freccia nella figura precedente, il flusso di dati di un binding può andare dalla destinazione del binding all'origine del binding (ad esempio, il valore di origine cambia quando un utente modifica il valore di un TextBox) e/o dall'origine dell'associazione per la destinazione del binding (ad esempio, il TextBox contenuto viene aggiornato con le modifiche nell'origine del binding) se l'origine del binding fornisce le notifiche appropriate.As mentioned previously and as indicated by the arrow in the figure above, 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 gets updated with changes in the binding source) if the binding source provides the proper notifications.

È possibile fare in modo che l'applicazione consenta agli utenti di modificare i dati e di propagarli all'oggetto di origineYou may want your application to enable users to change the data and propagate it back to the source object. oppure è possibile fare in modo che gli utenti non possano aggiornare i dati di origine.Or you may not want to enable users to update the source data. È possibile controllare questo impostando il Mode proprietà del Binding oggetto.You can control this by setting the Mode property of your Binding object. La figura seguente illustra i diversi tipi di flusso di dati:The following figure illustrates the different types of data flow:

Flusso di dati nel data bindingData binding data flow

  • OneWay Binding fa sì che le modifiche apportate alla proprietà di origine per aggiornare automaticamente la proprietà di destinazione, ma le modifiche apportate alla proprietà di destinazione non vengono propagate alla proprietà di origine.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. Questo tipo di binding è appropriato se il controllo da associare è implicitamente di sola lettura.This type of binding is appropriate if the control being bound is implicitly read-only. Può accadere ad esempio che si effettui un binding a un'origine quale un controllo Stock Ticker oppure che la proprietà di destinazione non possieda un'interfaccia di controllo tramite la quale apportare modifiche, come nel caso di un colore di sfondo con binding a dati di una tabella.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 non è necessario monitorare le modifiche delle proprietà di destinazione, l'uso della modalità di associazione OneWay consente di evitare il sovraccarico della modalità di binding 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.

  • TwoWay Binding fa sì che le modifiche alla proprietà di origine o la proprietà di destinazione per aggiornare automaticamente l'altra.TwoWay binding causes changes to either the source property or the target property to automatically update the other. Questo tipo di binding è adatto a moduli modificabili o ad altri scenari Interfaccia utenteUI completamente interattivi.This type of binding is appropriate for editable forms or other fully-interactive Interfaccia utenteUI scenarios. Per impostazione predefinita la maggior parte delle proprietà OneWay binding, ma alcune proprietà di dipendenza (in genere le proprietà dei controlli modificabili dall'utente, ad esempio il Text proprietà di TextBox e il IsChecked proprietà di CheckBox) predefinito per TwoWay dell'associazione.Most properties default to OneWay binding, but some dependency properties (typically properties of user-editable controls such as the Text property of TextBox and the IsChecked property of CheckBox) default to TwoWay binding. Un modo programmatico per determinare se l'associazione di una proprietà di dipendenza è unidirezionale o bidirezionale per impostazione predefinita, consiste nell'ottenere i metadati della proprietà con GetMetadata e quindi controllare il valore booleano della proprietà BindsTwoWayByDefault.A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata of the property using GetMetadata and then check the Boolean value of the BindsTwoWayByDefault property.

  • OneWayToSource è l'opposto di OneWay binding; Aggiorna la proprietà di origine quando cambia la proprietà di destinazione.OneWayToSource is the reverse of OneWay binding; it updates the source property when the target property changes. Può essere usata, ad esempio, nel caso in cui si debba semplicemente rivalutare il valore di origine dall'Interfaccia utenteUI.One example scenario is if you only need to re-evaluate the source value from the Interfaccia utenteUI.

  • Non è illustrata nella figura è OneTime associazione, in modo che la proprietà di origine inizializzare la proprietà di destinazione, ma non vengono propagate le modifiche successive.Not illustrated in the figure is OneTime binding, which causes the source property to initialize the target property, but subsequent changes do not propagate. Ciò significa che se il contesto dati subisce una modifica o l'oggetto nel contesto dati viene modificato, la modifica non si riflette nella proprietà di destinazione.This means that if the data context undergoes a change or the object in the data context changes, then the change is not reflected in the target property. Questo tipo di binding è appropriato per dati in cui è opportuno usare uno snapshot dello stato corrente o che sono realmente statici.This type of binding is appropriate if you are using data where either a snapshot of the current state is appropriate to use or the data is truly static. Questo tipo di binding è utile anche se si vuole inizializzare la proprietà di destinazione con un valore ricavato da una proprietà di origine e il contesto dei dati non è noto in anticipo.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. Si tratta essenzialmente di una forma più semplice di binding OneWay che offre prestazioni migliori nei casi in cui il valore di origine non cambia.This is essentially a simpler form of OneWay binding that provides better performance in cases where the source value does not change.

Si noti che per rilevare le modifiche di origine (applicabile per OneWay e TwoWay associazioni), l'origine deve implementare un meccanismo di notifica di modifica proprietà appropriato, ad esempio INotifyPropertyChanged.Note that to detect source changes (applicable to OneWay and TwoWay bindings), the source must implement a suitable property change notification mechanism such as INotifyPropertyChanged. Visualizzare implementare la notifica di modifica proprietà per un esempio di un INotifyPropertyChanged implementazione.See Implement Property Change Notification for an example of an INotifyPropertyChanged implementation.

Il Mode pagina delle proprietà fornisce altre informazioni sulle modalità di associazione e un esempio di come specificare la direzione di un'associazione.The Mode property page provides more information about binding modes and an example of how to specify the direction of a binding.

Eventi che generano gli aggiornamenti dell'origineWhat Triggers Source Updates

Le associazioni di tipo TwoWay o OneWayToSource ascoltare le modifiche alla proprietà di destinazione e quindi propagarli all'origine.Bindings that are TwoWay or OneWayToSource listen for changes in the target property and propagate them back to the source. Questo processo è noto come aggiornamento dell'origine.This is known as updating the source. Può accadere ad esempio che si modifichi il testo di un oggetto TextBox per modificare il valore di origine sottostante.For example, you may edit the text of a TextBox to change the underlying source value. Come descritto nella sezione precedente, la direzione del flusso di dati è determinata dal valore della Mode proprietà dell'associazione.As described in the last section, the direction of the data flow is determined by the value of the Mode property of the binding.

Il valore di origine viene aggiornato durante la modifica del testo o dopo aver apportato le modifiche del testo e aver spostato il mouse da TextBox?However, does your source value get updated while you are editing the text or after you finish editing the text and point your mouse away from the TextBox? Il UpdateSourceTrigger proprietà dell'associazione determina ciò che attiva l'aggiornamento dell'origine.The UpdateSourceTrigger property of the binding determines what triggers the update of the source. I puntini delle frecce a destra nella figura seguente viene illustrato il ruolo del UpdateSourceTrigger proprietà:The dots of the right arrows in the following figure illustrate the role of the UpdateSourceTrigger property:

Diagramma di UpdateSourceTriggerUpdateSourceTrigger diagram

Se il UpdateSourceTrigger valore è PropertyChanged, quindi il valore a cui punta di freccia a destra TwoWay o il OneWayToSource binding viene aggiornato non appena le modifiche alle proprietà di destinazione.If the UpdateSourceTrigger value is PropertyChanged, then the value pointed to by the right arrow of TwoWay or the OneWayToSource bindings gets updated as soon as the target property changes. Tuttavia, se il UpdateSourceTrigger valore è LostFocus, quindi tale valore viene aggiornato soltanto con il nuovo valore quando la proprietà di destinazione perde lo stato attivo.However, if the UpdateSourceTrigger value is LostFocus, then that value only gets updated with the new value when the target property loses focus.

Simile al Mode proprietà, proprietà di dipendenza diverse possiedono predefinite diverse UpdateSourceTrigger valori.Similar to the Mode property, different dependency properties have different default UpdateSourceTrigger values. Il valore predefinito per la maggior parte delle proprietà di dipendenza è PropertyChanged, mentre la proprietà Text ha il valore predefinito LostFocus.The default value for most dependency properties is PropertyChanged, while the Text property has a default value of LostFocus. Ciò significa che gli aggiornamenti dell'origine avvengono in genere ogni volta che le modifiche alle proprietà di destinazione, che va bene per CheckBoxes e altri controlli semplici.This means that source updates usually happen whenever the target property changes, which is fine for CheckBoxes and other simple controls. Nel caso dei campi di testo, tuttavia, l'esecuzione di un aggiornamento a ogni pressione di tasto può comportare un calo di prestazioni nonché negare all'utente la possibilità di tornare indietro e correggere eventuali errori di digitazione prima di confermare il nuovo valore.However, for text fields, updating after every keystroke can diminish performance and it denies the user the usual opportunity to backspace and fix typing errors before committing to the new value. Ecco perché il Text proprietà ha un valore predefinito di LostFocus invece di PropertyChanged.That is why the Text property has a default value of LostFocus instead of PropertyChanged.

Vedere le UpdateSourceTrigger pagina delle proprietà per informazioni su come trovare il valore predefinito UpdateSourceTrigger valore di una proprietà di dipendenza.See the UpdateSourceTrigger property page for information about how to find the default UpdateSourceTrigger value of a dependency property.

Nella tabella seguente fornisce uno scenario di esempio per ognuno UpdateSourceTrigger valore utilizzando il TextBox ad esempio:The following table provides an example scenario for each UpdateSourceTrigger value using the TextBox as an example:

Valore di UpdateSourceTriggerUpdateSourceTrigger value Quando il valore di origine viene aggiornatoWhen the Source Value Gets Updated Scenario di esempio per TextBoxExample Scenario for TextBox
LostFocus (valore predefinito per TextBox.Text)LostFocus (default for TextBox.Text) Quando il controllo TextBox perde lo stato attivoWhen the TextBox control loses focus Oggetto TextBox associata con la logica di convalida (vedere la sezione convalida dei dati)A TextBox that is associated with validation logic (see Data Validation section)
PropertyChangedPropertyChanged Durante la digitazione di TextBoxAs you type into the TextBox TextBox controlli in una finestra della chatTextBox controls in a chat room window
ExplicitExplicit Quando l'applicazione chiama UpdateSourceWhen the application calls UpdateSource TextBox controlli in un modulo modificabile (Aggiorna i valori di origine solo quando l'utente fa clic sul pulsante Invia)TextBox controls in an editable form (updates the source values only when the user clicks the submit button)

Per un esempio, vedere Procedura: Controllare il momento in cui il database di origine viene aggiornato dal testo di TextBox.For an example, see Control When the TextBox Text Updates the Source.

Creazione di un'associazioneCreating a Binding

Per riepilogare alcuni dei concetti illustrati nelle sezioni precedenti, si stabilisce un'associazione utilizzando il Binding oggetto e ogni associazione è in genere include quattro componenti: associazione di destinazione, la proprietà di destinazione, origine dell'associazione e un percorso per il valore di origine da utilizzare.To recapitulate some of the concepts discussed in the previous sections, you establish a binding using the Binding object, and each binding usually has four components: binding target, target property, binding source, and a path to the source value to use. Questa sezione illustra come impostare un binding.This section discusses how to set up a binding.

Si consideri l'esempio seguente, in cui l'oggetto origine del binding è una classe denominata MyData definita nello spazio dei nomi SDKSample.Consider the following example, in which the binding source object is a class named MyData that is defined in the SDKSample namespace. A scopo dimostrativo, la classe MyData dispone di una proprietà stringa denominata ColorName, il cui valore è impostato su "Red".For demonstration purposes, MyData class has a string property named ColorName, of which the value is set to "Red". L'esempio genera quindi un pulsante con uno sfondo rosso.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>

Per altre informazioni sulla sintassi della dichiarazione di binding e per esempi su come impostare un binding nel codice, vedere Cenni preliminari sulle dichiarazioni di binding.For more details on the binding declaration syntax and for examples of how to set up a binding in code, see Binding Declarations Overview.

Se si applica questo esempio al diagramma di base, la figura risultante sarà simile alla seguente.If we apply this example to our basic diagram, the resulting figure looks like the following. Si tratta di un OneWay associazione perché la proprietà Background supporta OneWay binding per impostazione predefinita.This is a OneWay binding because the Background property supports OneWay binding by default.

Diagramma di data bindingData binding diagram

È lecito chiedersi perché ciò funziona anche se il ColorName proprietà è di tipo stringa mentre la Background proprietà è di tipo Brush.You may wonder why this works even though the ColorName property is of type string while the Background property is of type Brush. In questo caso viene usata la conversione di tipi predefinita, descritta nella sezione Conversione dei dati.This is default type conversion at work and is discussed in the Data Conversion section.

Specifica dell'origine del bindingSpecifying the Binding Source

Si noti che nell'esempio precedente, l'origine del binding viene specificato impostando il DataContext proprietà di DockPanel elemento.Notice that in the previous example, the binding source is specified by setting the DataContext property on the DockPanel element. Il Button eredita quindi il DataContext valore il DockPanel, che costituisce l'elemento padre.The Button then inherits the DataContext value from the DockPanel, which is its parent element. Come già detto, l'oggetto origine del binding è uno dei quattro componenti necessari di un binding.To reiterate, the binding source object is one of the four necessary components of a binding. Se quindi non si specifica l'oggetto origine del binding, questa non viene creata.Therefore, without the binding source object being specified, the binding would do nothing.

Esistono diversi modi per specificare l'oggetto origine del binding.There are several ways to specify the binding source object. Uso di DataContext proprietà su un elemento padre è utile quando si associano più proprietà alla stessa origine.Using the DataContext property on a parent element is useful when you are binding multiple properties to the same source. In alcuni casi, tuttavia, è preferibile specificare l'origine del binding in singole dichiarazioni di binding.However, sometimes it may be more appropriate to specify the binding source on individual binding declarations. Per l'esempio precedente, invece di usare la DataContext proprietà, è possibile specificare l'origine del binding impostando la Source proprietà direttamente nella dichiarazione di binding del pulsante, come nell'esempio seguente:For the previous example, instead of using the DataContext property, you can specify the binding source by setting the Source property directly on the binding declaration of the button, as in the following example:

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

Diverso da impostare il DataContext proprietà su un elemento direttamente, che eredita le DataContext valore da un predecessore (ad esempio, il pulsante nel primo esempio) e specificare in modo esplicito l'origine del binding impostando il Source proprietà il Binding (ad esempio, il pulsante nell'ultimo esempio), è anche possibile usare la ElementName proprietà o il RelativeSource proprietà per specificare l'origine del binding.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 Source property on the Binding (such as the button the last example), you can also use the ElementName property or the RelativeSource property to specify the binding source. Il ElementName proprietà è utile quando si associa agli altri elementi dell'applicazione, ad esempio quando si utilizza un dispositivo di scorrimento per regolare la larghezza di un pulsante.The ElementName property is useful when you are binding to other elements in your application, such as when you are using a slider to adjust the width of a button. Il RelativeSource proprietà è utile quando è specificata l'associazione un ControlTemplate o un Style.The RelativeSource property is useful when the binding is specified in a ControlTemplate or a Style. Per altre informazioni, vedere Procedura: Specificare l'origine del binding.For more information, see Specify the Binding Source.

Specifica del percorso al valoreSpecifying the Path to the Value

Se l'origine del binding è un oggetto, si utilizza il Path proprietà per specificare il valore da usare per l'associazione.If your binding source is an object, you use the Path property to specify the value to use for your binding. Se si esegue l'associazione XMLXML dei dati, utilizzare il XPath proprietà per specificare il valore.If you are binding to XMLXML data, you use the XPath property to specify the value. In alcuni casi, potrebbe essere applicabile all'utilizzo di Path anche quando i dati sono di proprietà XMLXML.In some cases, it may be applicable to use the Path property even when your data is XMLXML. Ad esempio, se si vuole accedere alla proprietà Name di un XmlNode restituito (in seguito a una query XPath), è consigliabile usare la Path oltre alla proprietà di XPath proprietà.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.

Per informazioni sulla sintassi ed esempi, vedere la Path e XPath pagine delle proprietà.For syntax information and examples, see the Path and XPath property pages.

Si noti che, sebbene sia stato sottolineato che il Path al valore da usare è uno dei quattro componenti necessari di un binding, negli scenari che si desidera associare a un oggetto intero, il valore da usare sarebbe lo stesso dell'oggetto di origine di associazione.Note that 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 which you want to bind to an entire object, the value to use would be the same as the binding source object. In questi casi, è possibile non specificare un Path.In those cases, it is applicable to not specify a Path. Si consideri l'esempio seguente:Consider the following example:

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

L'esempio precedente usa la sintassi di binding vuota: {Binding}.The above example uses the empty binding syntax: {Binding}. In questo caso, il ListBox eredita DataContext da un elemento DockPanel padre (non illustrato in questo esempio).In this case, the ListBox inherits the DataContext from a parent DockPanel element (not shown in this example). Quando il percorso non viene specificato, per impostazione predefinita si esegue un binding all'intero oggetto.When the path is not specified, the default is to bind to the entire object. In altre parole, in questo esempio, il percorso è stato tralasciato poiché la ItemsSource proprietà per l'intero oggetto.In other words, in this example, the path has been left out because we are binding the ItemsSource property to the entire object. Per informazioni più dettagliate, vedere la sezione Binding alle raccolte.(See the Binding to Collections section for an in-depth discussion.)

Oltre al binding a una raccolta, questo scenario è utile anche in caso di binding a un intero oggetto anziché a una singola proprietà di un oggetto.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. Si consideri ad esempio un oggetto origine di tipo stringa con un binding alla stringa stessa.For example, if your source object is of type string and you simply want to bind to the string itself. Un altro scenario comune riguarda il binding di un elemento a un oggetto con numerose proprietà.Another common scenario is when you want to bind an element to an object with several properties.

Affinché i dati siano significativi per la proprietà di destinazione associata, può essere necessario applicare logica personalizzata.Note that you may need to apply custom logic so that the data is meaningful to your bound target property. Tale logica potrebbe essere un convertitore personalizzato, in assenza della conversione di tipi predefinita.The custom logic may be in the form of a custom converter (if default type conversion does not exist). Per informazioni sui convertitori, vedere Conversione dei dati.See Data Conversion for information about converters.

Binding e BindingExpressionBinding and BindingExpression

Prima di approfondire altri utilizzi del data binding e funzionalità, potrebbe essere utile per introdurre il BindingExpression classe.Before getting into other features and usages of data binding, it would be useful to introduce the BindingExpression class. Come si è visto nelle sezioni precedenti, il Binding è la classe generale per la dichiarazione di un'associazione; il Binding classe include diverse proprietà che consentono di specificare le caratteristiche di un'associazione.As you have seen in previous sections, the Binding class is the high-level class for the declaration of a binding; the Binding class provides many properties that allow you to specify the characteristics of a binding. Una classe correlata, BindingExpression, corrisponde all'oggetto sottostante che gestisce la connessione tra l'origine e destinazione.A related class, BindingExpression, is the underlying object that maintains the connection between the source and the target. Un binding contiene tutte le informazioni condivisibili tra diverse espressioni di binding.A binding contains all the information that can be shared across several binding expressions. Oggetto BindingExpression è un'espressione dell'istanza condivisibile e contiene tutte le informazioni sull'istanza del Binding.A BindingExpression is an instance expression that cannot be shared and contains all the instance information of the Binding.

Ad esempio, tenere presente quanto segue, dove myDataObject è un'istanza di MyData (classe), myBinding è l'origine Binding oggetto ed MyData classe è una classe definita contenente una proprietà stringa denominata MyDataProperty.For example, consider the following, where myDataObject is an instance of MyData class, myBinding is the source Binding object, and MyData class is a defined class that contains a string property named MyDataProperty. Questo esempio associa il contenuto di testo mytext, un'istanza di TextBlock, al MyDataProperty.This example binds the text content of mytext, an instance of TextBlock, to MyDataProperty.

// Make a new source.
MyData myDataObject = new MyData(DateTime.Now);      
Binding myBinding = new Binding("MyDataProperty");
myBinding.Source = myDataObject;
// Bind the new data source to the myText TextBlock control's Text dependency property.
myText.SetBinding(TextBlock.TextProperty, myBinding);
' Make a new source.
Dim data1 As New MyData(DateTime.Now)
Dim binding1 As New Binding("MyDataProperty")
binding1.Source = data1
' Bind the new data source to the myText TextBlock control's Text dependency property.
Me.myText.SetBinding(TextBlock.TextProperty, binding1)

È possibile usare lo stesso oggetto myBinding per creare altri binding.You can use the same myBinding object to create other bindings. È ad esempio possibile usare l'oggetto myBinding per associare il contenuto di testo di una casella di controllo di testo a MyDataProperty.For example, you may use myBinding object to bind the text content of a check box to MyDataProperty. In questo scenario, saranno presenti due istanze del BindingExpression condividere la myBinding oggetto.In that scenario, there will be two instances of BindingExpression sharing the myBinding object.

Oggetto BindingExpression oggetto può essere ottenuto tramite il valore restituito della chiamata al metodo GetBindingExpression su un oggetto con associazione a dati.A BindingExpression object can be obtained through the return value of calling GetBindingExpression on a data-bound object. Gli argomenti seguenti vengono illustrati alcuni degli utilizzi del BindingExpression classe:The following topics demonstrate some of the usages of the BindingExpression class:

Conversione dei datiData Conversion

Nell'esempio precedente, il pulsante è rosso perché relativo Background proprietà è associata a una proprietà di stringa con il valore "Red".In the previous example, the button is red because its Background property is bound to a string property with the value "Red". Questo procedimento funziona perché è presente in un convertitore di tipi di Brush tipo in cui convertire il valore della stringa un Brush.This works because a type converter is present on the Brush type to convert the string value to a Brush.

Se si aggiungono queste informazioni alla figura nella sezione Creazione di un binding, si ottiene un diagramma analogo al seguente:To add this information to the figure in the Creating a Binding section, the diagram looks like the following:

Diagramma di data bindingData binding diagram

Cosa accade però se anziché una proprietà di stringa del tipo di oggetto origine del binding è un colore vlastnosti typu Color?However, what if instead of having a property of type string your binding source object has a Color property of type Color? In tal caso, affinché l'associazione da usare è necessario prima disattivare la colore valore della proprietà in un elemento che il Background proprietà accetta.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. È necessario creare un convertitore personalizzato implementando il IValueConverter interfaccia, come nell'esempio seguente: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

Il IValueConverter pagina di riferimento vengono fornite ulteriori informazioni.The IValueConverter reference page provides more information.

Il convertitore personalizzato viene ora usato al posto della conversione predefinita e il diagramma si presenta come segue:Now the custom converter is used instead of default conversion, and our diagram looks like this:

Diagramma di data bindingData binding diagram

Come già detto, le conversioni predefinite possono essere disponibili o meno a seconda dei convertitori presenti nel tipo a cui si esegue il binding.To reiterate, default conversions may be available because of type converters that are present in the type being bound to. Questo comportamento dipenderà dai convertitori di tipi disponibili nella destinazione.This behavior will depend on which type converters are available in the target. In caso di dubbio, creare un convertitore personalizzato.If in doubt, create your own converter.

Vengono riportati di seguito alcuni scenari tipici in cui è opportuno implementare un convertitore di dati:Following are some typical scenarios where it makes sense to implement a data converter:

  • I dati devono essere visualizzati in modo diverso, a seconda delle impostazioni cultura.Your data should be displayed differently, depending on culture. È ad esempio possibile implementare un convertitore di valuta o un convertitore di data/ora nel calendario in base ai valori o agli standard usati in specifiche impostazioni cultura.For instance, you might want to implement a currency converter or a calendar date/time converter based on the values or standards used in a particular culture.

  • I dati usati non devono necessariamente modificare il valore di testo di una proprietà quanto piuttosto altri valori, ad esempio l'origine di un'immagine oppure il colore o lo stile del testo visualizzato.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. I convertitori possono essere usati in questo caso per convertire il binding di una proprietà considerata poco appropriata, ad esempio il binding di un campo di testo alla proprietà Background della cella di una tabella.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.

  • Più controlli o più proprietà dei controlli sono associati agli stessi dati.More than one control or to multiple properties of controls are bound to the same data. In questo caso, il binding primario potrebbe semplicemente visualizzare il testo, mentre gli altri binding gestiscono problemi di visualizzazione specifici, usando comunque lo stesso binding come informazione di origine.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.

  • Finora abbiamo non ancora analizzato MultiBinding, in una proprietà di destinazione è una raccolta di associazioni.So far we have not yet discussed MultiBinding, where a target property has a collection of bindings. Nel caso di un MultiBinding, si utilizza un oggetto personalizzato IMultiValueConverter per produrre un valore finale dai valori delle associazioni.In the case of a MultiBinding, you use a custom IMultiValueConverter to produce a final value from the values of the bindings. È possibile ad esempio calcolare il colore dai valori rosso, blu e verde, ovvero valori che possono provenire da oggetti origine del binding identici o diversi.For example, color may be computed from red, blue, and green values, which can be values from the same or different binding source objects. Vedere il MultiBinding pagina relativa alla classe per informazioni ed esempi.See the MultiBinding class page for examples and information.

Binding alle raccolteBinding to Collections

Un oggetto origine del binding può essere considerato come un unico oggetto le cui proprietà contengono dati oppure come una raccolta di dati di oggetti polimorfici che spesso vengono raggruppati. Un esempio può essere il risultato di una query in un database.A binding source object can be treated either as a single object of which the 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). È stato finora illustrato solo il binding a singoli oggetti. Esiste tuttavia un altro scenario comune che è il binding a una raccolta di dati.So far we've only discussed binding to single objects, however, binding to a data collection is a common scenario. Ad esempio, uno scenario comune consiste nell'usare un ItemsControl , ad esempio un ListBox, ListView, o TreeView per visualizzare una raccolta di dati, come avviene nell'applicazione illustrata nella What ' s Data Binding? sezione.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 application shown in the What Is Data Binding? section.

Anche in questo caso è possibile applicare il diagramma di base.Fortunately, our basic diagram still applies. Quando si associa un ItemsControl a una raccolta, il diagramma appare come segue:If you are binding an ItemsControl to a collection, the diagram looks like this:

Diagramma di data binding di ItemsControlData binding ItemsControl diagram

Come illustrato nella figura seguente, per associare un' ItemsControl a un oggetto collection, ItemsSource è la proprietà da utilizzare.As shown in this diagram, to bind an ItemsControl to a collection object, ItemsSource property is the property to use. È possibile pensare ItemsSource come contenuto della proprietà di ItemsControl.You can think of ItemsSource property as the content of the ItemsControl. Si noti che è l'associazione OneWay perché il ItemsSource supporta proprietà OneWay binding per impostazione predefinita.Note that the binding is OneWay because the ItemsSource property supports OneWay binding by default.

Come implementare le raccolteHow to Implement Collections

È possibile enumerare in qualsiasi raccolta che implementa il IEnumerable interfaccia.You can enumerate over any collection that implements the IEnumerable interface. Tuttavia, per impostare i binding dinamici in modo che gli inserimenti o eliminazioni nella raccolta di aggiornino il Interfaccia utenteUI automaticamente, la raccolta deve implementare il INotifyCollectionChanged interfaccia.However, to set up dynamic bindings so that insertions or deletions in the collection update the Interfaccia utenteUI automatically, the collection must implement the INotifyCollectionChanged interface. Questa interfaccia espone un evento che deve essere generato a ogni modifica della raccolta sottostante.This interface exposes an event that should be raised whenever the underlying collection changes.

WPFWPF fornisce il ObservableCollection<T> classe, ovvero un'implementazione incorporata di una raccolta di dati che espone il INotifyCollectionChanged interfaccia. provides the ObservableCollection<T> class, which is a built-in implementation of a data collection that exposes the INotifyCollectionChanged interface. Si noti che per supportare pienamente il trasferimento dei valori dei dati dagli oggetti di origine alle destinazioni, ogni oggetto nella raccolta che supporta proprietà associabili deve implementare anche il INotifyPropertyChanged interfaccia.Note that 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. Per altre informazioni, vedere Cenni preliminari sulle origini del binding.For more information, see Binding Sources Overview.

Prima di implementare una raccolta personalizzata, è consigliabile usare ObservableCollection<T> o una delle raccolte esistenti classi, ad esempio List<T>, Collection<T>, e BindingList<T>, tra le molte altre.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 si dispone di uno scenario avanzato e si vuole implementare una raccolta personalizzata, è consigliabile usare IList, che fornisce una raccolta non generica di oggetti che è possibile accedere singolarmente tramite indice e garantisce prestazioni ottimali.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 index and thus the best performance.

Visualizzazioni di raccolteCollection Views

Una volta il ItemsControl è associato a una raccolta di dati, è possibile ordinare, filtrare o raggruppare i dati.Once your ItemsControl is bound to a data collection, you may want to sort, filter, or group the data. A tale scopo, si usano le visualizzazioni di raccolta, che sono classi che implementano il ICollectionView interfaccia.To do that, you use collection views, which are classes that implement the ICollectionView interface.

Definizione di visualizzazione di raccoltaWhat Are Collection Views?

Una visualizzazione di raccolta rappresenta il livello superiore di una raccolta di origine di binding che consente di esplorare e visualizzare la raccolta di origine in base a query di ordinamento, filtro e raggruppamento, il tutto senza modificare la raccolta di origine sottostante.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. Una visualizzazione di raccolta mantiene inoltre un puntatore all'elemento corrente nella raccolta.A collection view also maintains a pointer to the current item in the collection. Se la raccolta di origine implementa il INotifyCollectionChanged dell'interfaccia, le modifiche generate dalla CollectionChanged evento vengono propagate alle visualizzazioni.If the source collection implements the INotifyCollectionChanged interface, the changes raised by the CollectionChanged event are propagated to the views.

Poiché le visualizzazioni non modificano le raccolte di origine sottostanti, ogni raccolta di origine può avere più visualizzazioni associate.Because views do not change the underlying source collections, each source collection can have multiple views associated with it. Si consideri ad esempio una raccolta di oggetti Task.For example, you may have a collection of Task objects. Grazie alle visualizzazioni è possibile visualizzare gli stessi dati in modi diversi.With the use of views, you can display that same data in different ways. È possibile ad esempio visualizzare le attività ordinate in base alla priorità nella parte sinistra della pagina e, contemporaneamente nella parte destra, visualizzare le stesse attività raggruppate in base all'area.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.

Come creare una visualizzazioneHow to Create a View

Per creare e usare una visualizzazione, è possibile creare direttamente un'istanza dell'oggetto visualizzazione e usare tale istanza come origine del binding.One way to create and use a view is to instantiate the view object directly and then use it as the binding source. Si consideri ad esempio l'applicazione Demo di data binding mostrata nella sezione Definizione di data binding.For example, consider the Data Binding Demo application shown in the What Is Data Binding? section. L'applicazione viene implementata in modo che il ListBox associa direttamente a una visualizzazione della raccolta di dati anziché la raccolta dei dati.The application is implemented such that the ListBox binds to a view over the data collection instead of the data collection directly. L'esempio seguente è stato estratto dall'applicazione Demo di data binding.The following example is extracted from the Data Binding Demo application. Il CollectionViewSource classe è il Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) proxy di una classe che eredita da CollectionView.The CollectionViewSource class is the Extensible Application Markup Language (XAML)Extensible Application Markup Language (XAML) proxy of a class that inherits from CollectionView. In questo particolare esempio, il Source della visualizzazione è associata ai AuctionItems raccolta (di tipo ObservableCollection<T>) dell'oggetto applicazione corrente.In this particular example, the Source of the view is bound to the AuctionItems collection (of type ObservableCollection<T>) of the current application object.

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

La risorsa listingDataView viene quindi usato come origine del binding per gli elementi nell'applicazione, ad esempio il ListBox:The resource listingDataView then serves as the binding source for elements in the application, such as the ListBox:

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

Per creare un'altra visualizzazione per la stessa raccolta, è possibile creare un'altra CollectionViewSource dell'istanza e assegnargli un diverso x:Key nome.To create another view for the same collection, you can create another CollectionViewSource instance and give it a different x:Key name.

La tabella seguente illustra i tipi di dati di visualizzazione vengono creati come visualizzazione raccolta predefinita o tramite CollectionViewSource in base al tipo di raccolta di origine.The following table shows which view data types are created as the default collection view or by CollectionViewSource based on the source collection type.

Tipo di raccolta di origineSource collection type Tipo di visualizzazione di raccoltaCollection view type NoteNotes
IEnumerable Un tipo interno basato sul CollectionViewAn internal type based on CollectionView Non è possibile raggruppare gli elementi.Cannot group items.
IList ListCollectionView Il più veloce.Fastest.
IBindingList BindingListCollectionView
Utilizzo di una visualizzazione predefinitaUsing a Default View

Specificare una visualizzazione di raccolta come origine di binding rappresenta un modo per creare e usare una visualizzazione di raccolta.Specifying a collection view as a binding source is one way to create and use a collection view. WPF crea inoltre una visualizzazione di raccolta predefinita per ogni raccolta usata come origine di binding.WPF also creates a default collection view for every collection used as a binding source. Se si esegue il binding direttamente a una raccolta, WPF esegue il binding alla relativa visualizzazione predefinita.If you bind directly to a collection, WPF binds to its default view. Questa visualizzazione predefinita è condivisa da tutti i binding alla stessa raccolta, pertanto una modifica apportata a una visualizzazione predefinita da un controllo associato o dal codice, ad esempio l'ordinamento o una modifica al puntatore dell'elemento corrente illustrati più avanti, viene riflessa in tutti gli altri binding alla stessa raccolta.Note that 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.

Per ottenere la visualizzazione predefinita, si utilizza il GetDefaultView (metodo).To get the default view, you use the GetDefaultView method. Per un esempio, vedere Procedura: ottenere la visualizzazione predefinita di una raccolta di dati.For an example, see Get the Default View of a Data Collection.

Visualizzazioni di raccolta con ADO.NET DataTableCollection Views with ADO.NET DataTables

Per migliorare le prestazioni, le visualizzazioni di raccolta per ADO.NET DataTable oppure DataView oggetti delegano l'ordinamento e filtraggio del contenuto per il DataView.To improve performance, collection views for ADO.NET DataTable or DataView objects delegate sorting and filtering to the DataView. L'ordinamento e il filtro vengono in tal modo condivisi in tutte le visualizzazioni di raccolta dell'origine dati.This causes sorting and filtering to be shared across all collection views of the data source. Per consentire a ogni vista di raccolta ordinare e filtrare in modo indipendente, inizializzare ogni visualizzazione di raccolta con il proprio DataView oggetto.To enable each collection view to sort and filter independently, initialize each collection view with its own DataView object.

OrdinamentoSorting

Come detto in precedenza, le visualizzazioni possono applicare un ordinamento a una raccolta.As mentioned before, views can apply a sort order to a collection. Poiché esistono nella raccolta sottostante, i dati possono avere o non avere un ordine intrinseco.As it exists in the underlying collection, your data may or may not have a relevant, inherent order. La visualizzazione della raccolta consente di imporre un ordine o di modificare l'ordine predefinito in base ai criteri di confronto che si forniscono.The view over the collection allows you to impose an order, or change the default order, based on comparison criteria that you supply. Trattandosi di una visualizzazione dei dati basata su client, uno scenario comune prevede che l'utente possa ordinare le colonne di dati tabulari in base al valore al quale corrisponde la colonna.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. Grazie alle visualizzazioni, è possibile applicare questo ordinamento gestito dall'utente senza apportare alcuna modifica alla raccolta sottostante né dover ripetere la query nel contenuto della raccolta.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. Per un esempio, vedere Procedura: Ordinare una colonna GridView quando si fa clic su un'intestazione.For an example, see Sort a GridView Column When a Header Is Clicked.

L'esempio seguente illustra la logica di ordinamento di "Sort by category and date" CheckBox dell'applicazione Interfaccia utenteUI nel What ' s Data Binding? sezione:The following example shows the sorting logic of the "Sort by category and date" CheckBox of the application Interfaccia utenteUI in the What Is Data Binding? section:

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

FiltroFiltering

Le visualizzazioni possono anche applicare un filtro a una raccolta.Views can also apply a filter to a collection. In altre parole, anche se una raccolta può includere un elemento, questa specifica visualizzazione è progettata per visualizzare solo un determinato subset di una raccolta completa.This means that although an item might exist in the collection, this particular view is intended to show only a certain subset of the full collection. I dati possono essere filtrati in base a una condizione.You might filter on a condition in the data. Ad esempio, come avviene per l'applicazione nel What ' s Data Binding? sezione, "Mostra solo bargains" CheckBox contiene la logica per filtrare gli elementi con un costo di $25 o più.For instance, as is done by the application in the What Is Data Binding? section, the "Show only bargains" CheckBox contains logic to filter out items that cost $25 or more. Viene eseguito il codice seguente per impostare ShowOnlyBargainsFilter come la Filter gestore evento quando che CheckBox è selezionato:The following code is executed to set ShowOnlyBargainsFilter as the Filter event handler when that CheckBox is selected:

listingDataView.Filter += new FilterEventHandler(ShowOnlyBargainsFilter);
AddHandler listingDataView.Filter, AddressOf ShowOnlyBargainsFilter

L'implementazione dell'evento ShowOnlyBargainsFilter è la seguente:The ShowOnlyBargainsFilter event handler has the following implementation:

private void ShowOnlyBargainsFilter(object sender, FilterEventArgs e)
{
    AuctionItem product = e.Item as AuctionItem;
    if (product != null)
    {
        // Filter out products with price 25 or above
        if (product.CurrentPrice < 25)
        {
            e.Accepted = true;
        }
        else
        {
            e.Accepted = false;
        }
    }
}
Private Sub ShowOnlyBargainsFilter(ByVal sender As Object, ByVal e As FilterEventArgs)
    Dim product As AuctionItem = CType(e.Item, AuctionItem)
    If Not (product Is Nothing) Then
        'Filter out products with price 25 or above
        If product.CurrentPrice < 25 Then
            e.Accepted = True
        Else
            e.Accepted = False
        End If
    End If
End Sub

Se si usa uno dei CollectionView classi direttamente anziché CollectionViewSource, si utilizzerebbe il Filter proprietà per specificare un callback.If you are using one of the CollectionView classes directly instead of CollectionViewSource, you would use the Filter property to specify a callback. Per un esempio, vedere Procedura: Filtrare i dati in una visualizzazione.For an example, see Filter Data in a View.

RaggruppamentoGrouping

Fatta eccezione per la classe interna che visualizza un IEnumerable raccolta, tutte le visualizzazioni di raccolta supportano la funzionalità di raggruppamento, che consente all'utente di suddividere la raccolta nella visualizzazione dell'insieme in gruppi logici.Except for the internal class that views an IEnumerable collection, all collection views support the functionality of grouping, which allows the user to partition the collection in the collection view into logical groups. Se l'utente fornisce un elenco di gruppi, questi saranno espliciti. Se invece i gruppi vengono generati in modo dinamico in base ai dati, si avranno gruppi impliciti.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.

L'esempio seguente illustra la logica di "Group by category" CheckBox:The following example shows the logic of the "Group by category" CheckBox:

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

Per un altro esempio di raggruppamento, vedere Procedura: Raggruppare gli elementi di un controllo ListView che implementa una GridView.For another grouping example, see Group Items in a ListView That Implements a GridView.

Puntatori dell'elemento correnteCurrent Item Pointers

Le visualizzazioni supportano anche la nozione di elemento corrente.Views also support the notion of a current item. In una visualizzazione di raccolta è possibile spostarsi da un oggetto all'altro.You can navigate through the objects in a collection view. Durante lo spostamento viene spostato un puntatore dell'elemento che consente di recuperare l'oggetto presente in un percorso specifico nella raccolta.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. Per un esempio, vedere Procedura: Navigare tra gli oggetti nella visualizzazione di una raccolta dati.For an example, see Navigate Through the Objects in a Data CollectionView.

Poiché WPF esegue il binding a una raccolta solo tramite una visualizzazione, che può essere sia una visualizzazione specificata dall'utente che la visualizzazione predefinita della raccolta, tutti i binding alle raccolte contengono un puntatore dell'elemento corrente.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. Quando si esegue il binding a una visualizzazione, il carattere barra ("/") in un valore di Path definisce l'elemento corrente della visualizzazione.When binding to a view, the slash ("/") character in a Path value designates the current item of the view. Nell'esempio seguente il contesto di dati è una visualizzazione di raccolta.In the following example, the data context is a collection view. La prima riga viene associata alla raccolta.The first line binds to the collection. La seconda riga viene associata all'elemento corrente della raccolta.The second line binds to the current item in the collection. La terza riga viene associata alla proprietà Description dell'elemento corrente nella raccolta.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}" />   

La barra e la sintassi della proprietà possono inoltre essere sovrapposte per attraversare una gerarchia di raccolte.The slash and property syntax can also be stacked to traverse a hierarchy of collections. Nell'esempio seguente viene eseguito il binding all'elemento corrente di una raccolta denominata Offices, che è una proprietà dell'elemento corrente della raccolta di origine.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/}" />  

Il puntatore dell'elemento corrente può essere influenzato da un'operazione di ordinamento o filtro applicata alla raccolta.The current item pointer can be affected by any sorting or filtering that is applied to the collection. L'ordinamento mantiene il puntatore dell'elemento corrente sull'ultimo elemento selezionato, ma la visualizzazione di raccolta viene ristrutturata in base a tale elemento.Sorting preserves the current item pointer on the last item selected, but the collection view is now restructured around it. Se in precedenza l'elemento selezionato si trovava all'inizio dell'elenco, ora è possibile che si trovi in posizione centrale. Il filtro mantiene l'elemento selezionato se la selezione rimane nella visualizzazione dopo l'applicazione del filtro.(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. Il puntatore dell'elemento corrente viene altrimenti impostato sul primo elemento della visualizzazione di raccolta filtrata.Otherwise, the current item pointer is set to the first item of the filtered collection view.

Scenario di binding master-dettagliMaster-Detail Binding Scenario

La nozione di elemento corrente è utile non solo per l'esplorazione degli elementi in una raccolta, bensì anche per lo scenario di binding master-dettagli.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. Si consideri nuovamente l'Interfaccia utenteUI dell'applicazione presentata nella sezione Definizione di data binding.Consider the application Interfaccia utenteUI in the What Is Data Binding? section again. In tale applicazione, la selezione all'interno di ListBox determina il contenuto visualizzato nel ContentControl.In that application, the selection within the ListBox determines the content shown in the ContentControl. Inserirlo in un altro modo, quando un ListBox elemento è selezionato, il ContentControl Mostra i dettagli dell'elemento selezionato.To put it in another way, when a ListBox item is selected, the ContentControl shows the details of the selected item.

Per implementare lo scenario master-dettagli, occorre semplicemente avere due o più controlli associati alla stessa visualizzazione.You can implement the master-detail scenario simply by having two or more controls bound to the same view. Nell'esempio seguente il Demo di Data Binding viene illustrato il markup delle ListBox e il ContentControl viene visualizzato nell'applicazione Interfaccia utenteUI nel What ' s Data Binding? sezione:The following example from the Data Binding Demo shows the markup of the ListBox and the ContentControl you see on the application Interfaccia utenteUI in the What Is Data Binding? section:

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

Si noti che entrambi i controlli sono associati alla stessa origine, vale a dire la risorsa statica listingDataView. Vedere a tale proposito la definizione di questa risorsa nella sezione Come creare una visualizzazione.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). Questo procedimento funziona perché quando un oggetto singleton (il ContentControl in questo caso) è associato a una vista di raccolta, viene automaticamente associato ai CurrentItem della visualizzazione.This 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. Si noti che CollectionViewSource oggetti sincronizzano automaticamente valuta e selezione.Note that CollectionViewSource objects automatically synchronize currency and selection. Se l'elenco non è associato a un CollectionViewSource dell'oggetto come in questo esempio, è necessario impostare relativi IsSynchronizedWithCurrentItem proprietà true per il corretto funzionamento.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.

Per altri esempi, vedere Procedura: Eseguire il binding di una raccolta e visualizzare informazioni in base alla selezione effettuata e Procedura: Utilizzare il modello master-dettagli con dati gerarchici.For other examples, see Bind to a Collection and Display Information Based on Selection and Use the Master-Detail Pattern with Hierarchical Data.

Come si può notare, l'esempio precedente usa un modello.You may have noticed that the above example uses a template. In effetti, i dati potrebbero non essere visualizzati come desiderato senza l'uso dei modelli (quello usato in modo esplicito dal ContentControl e quella usata in modo implicito dal 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). Le sezione seguente illustra i modelli di dati.We now turn to data templating in the next section.

Modelli di datiData Templating

Senza l'utilizzo di modelli di dati, l'Interfaccia utenteUI dell'applicazione illustrata nella sezione Definizione di data binding avrebbe un aspetto simile al seguente:Without the use of data templates, our application Interfaccia utenteUI in the What Is Data Binding? section would look like the following:

Demo di data binding senza modelli di datiData Binding Demo without Data Templates

Come illustrato nell'esempio nella sezione precedente, sia la ListBox controllo e il ContentControl associati all'intero oggetto collection (o più in particolare, la visualizzazione sull'oggetto collection) di AuctionItems.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. Senza istruzioni specifiche visualizzare la raccolta dei dati, il ListBox Visualizza una rappresentazione di stringa di ogni oggetto nella raccolta sottostante e ContentControl Visualizza una rappresentazione di stringa dell'oggetto è associato a.Without specific instructions of how to display the data collection, the ListBox is displaying a string representation of each object in the underlying collection and the ContentControl is displaying a string representation of the object it is bound to.

Per risolvere il problema, l'applicazione definisce DataTemplates.To solve that problem, the application defines DataTemplates. Come illustrato nell'esempio nella sezione precedente, il ContentControl utilizza in modo esplicito il detailsProductListingTemplateDataTemplate.As shown in the example in the previous section, the ContentControl explicitly uses the detailsProductListingTemplateDataTemplate. Il ListBox controllo utilizza in modo implicito le seguenti DataTemplate quando si visualizzano le AuctionItem oggetti nella raccolta:The ListBox control implicitly uses the following DataTemplate 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>

Grazie all'uso di questi due DataTemplates, l'interfaccia utente risultante è quella illustrata nella What ' s Data Binding? sezione.With the use of those two DataTemplates, the resulting UI is the one shown in the What Is Data Binding? section. Come può notare dallo screenshot, oltre a consentendo agli sviluppatori di inserimento di dati all'interno dei controlli, DataTemplates consentono di definire gli oggetti visivi accattivanti per i dati.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. Ad esempio, DataTriggervengono usati nell'esempio precedente DataTemplate in modo che AuctionItems con SpecialFeatures pari evidenziare verrebbe visualizzato con un bordo arancione e una stella.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.

Per altre informazioni sui modelli di dati, vedere Cenni preliminari sui modelli di dati.For more information about data templates, see the Data Templating Overview.

Convalida dei datiData Validation

La maggior parte delle applicazioni che accettano input dell'utente deve avere una logica di convalida per garantire che l'utente immetta le informazioni previste.Most applications that take user input need to have validation logic to ensure that the user has entered the expected information. I controlli di convalida possono basarsi sul tipo, l'intervallo, il formato o altri requisiti specifici dell'applicazione.The validation checks can be based on type, range, format, or other application-specific requirements. Questa sezione illustra il funzionamento della convalida dei dati in WPFWPF.This section discusses how data validation works in the WPFWPF.

Associazione di regole di convalida a un bindingAssociating Validation Rules with a Binding

Il WPFWPF modello di data binding, è possibile associare ValidationRules con il Binding oggetto.The WPFWPF data binding model allows you to associate ValidationRules with your Binding object. Ad esempio, l'esempio seguente associa un TextBox a una proprietà denominata StartPrice e aggiunge un ExceptionValidationRule dell'oggetto per il Binding.ValidationRules proprietà.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" Grid.Column="1"
    Style="{StaticResource textStyleTextBox}" Margin="8,5,0,5">
  <TextBox.Text>
    <Binding Path="StartPrice" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <ExceptionValidationRule />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>

Oggetto ValidationRule oggetto controlla se il valore di una proprietà è valido.A ValidationRule object checks whether the value of a property is valid. WPFWPF contiene i due tipi seguenti incorporati ValidationRule oggetti: has the following two types of built-in ValidationRule objects:

È anche possibile creare la regola di convalida derivando dal ValidationRule classe e l'implementazione di Validate (metodo).You can also create your own validation rule by deriving from the ValidationRule class and implementing the Validate method. L'esempio seguente mostra la regola usata dal Add Product Listing "Start Date" TextBox dal What ' s Data Binding? sezione:The following example shows the rule used by the Add Product Listing "Start Date" TextBox from the What Is Data Binding? section:

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

    Public Overrides Function Validate(ByVal value As Object,
                                       ByVal cultureInfo As System.Globalization.CultureInfo) _
                                   As System.Windows.Controls.ValidationResult

        Dim DateVal As DateTime

        Try
            DateVal = DateTime.Parse(value.ToString)
        Catch ex As FormatException
            Return New ValidationResult(False, "Value is not a valid date.")
        End Try

        If DateTime.Now.Date > DateVal Then
            Return New ValidationResult(False, "Please enter a date in the future.")
        Else
            Return ValidationResult.ValidResult
        End If
    End Function
End Class

Il StartDateEntryForm TextBox utilizza questo FutureDateRule, come illustrato nell'esempio seguente:The StartDateEntryForm TextBox uses this FutureDateRule, as shown in the following example:

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

Si noti che poiché il UpdateSourceTrigger valore è PropertyChanged, il motore di binding aggiorna il valore di origine a ogni pressione di tasto, il che significa che anche controlli di ogni regola nella ValidationRules insieme a ogni pressione di tasto.Note that 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. L'argomento verrà ulteriormente trattato nella sezione Processo di convalida.We discuss this further in the Validation Process section.

Visualizzazione di un feedbackProviding Visual Feedback

Se l'utente immette un valore non valido, è possibile fornire un feedback relativo all'errore nell'Interfaccia utenteUI dell'applicazione.If the user enters an invalid value, you may want to provide some feedback about the error on the application Interfaccia utenteUI. Un modo per fornire tale feedback consiste nell'impostare il Validation.ErrorTemplate proprietà associata a un oggetto personalizzato ControlTemplate.One way to provide such feedback is to set the Validation.ErrorTemplate attached property to a custom ControlTemplate. Come illustrato nella sottosezione precedente, il StartDateEntryForm TextBox utilizza una ErrorTemplate chiamato validationTemplate.As shown in the previous subsection, the StartDateEntryForm TextBox uses an ErrorTemplate called validationTemplate. L'esempio seguente illustra la definizione di validationTemplate:The following example shows the definition of validationTemplate:

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

Il AdornedElementPlaceholder elemento specifica dove deve essere posizionato il controllo decorato.The AdornedElementPlaceholder element specifies where the control being adorned should be placed.

Inoltre, è anche possibile usare un ToolTip per visualizzare il messaggio di errore.In addition, you may also use a ToolTip to display the error message. Entrambi i StartDateEntryForm e il StartPriceEntryFormTextBoxusano lo stile textStyleTextBox, che consente di creare un ToolTip che Visualizza il messaggio di errore.Both the StartDateEntryForm and the StartPriceEntryFormTextBoxes use the style textStyleTextBox, which creates a ToolTip that displays the error message. L'esempio seguente illustra la definizione di textStyleTextBox.The following example shows the definition of textStyleTextBox. La proprietà associata HasError è true quando uno o più binding nelle proprietà dell'elemento associato sono in errore.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>

Con l'oggetto personalizzato ErrorTemplate e il ToolTip, il StartDateEntryForm TextBox simile al seguente quando si verifica un errore di convalida:With the custom ErrorTemplate and the ToolTip, the StartDateEntryForm TextBox looks like the following when there is a validation error:

Errore di convalida di data bindingData binding validation error

Se il Binding dispone di regole di convalida associate ma non si specifica un' ErrorTemplate nel controllo associato, predefinito ErrorTemplate verrà usato per inviare notifiche agli utenti quando si verifica un errore di convalida.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. Il valore predefinito ErrorTemplate è un modello di controllo che definisce un bordo rosso nel livello dello strumento decorativo visuale.The default ErrorTemplate is a control template that defines a red border in the adorner layer. Con il valore predefinito ErrorTemplate e il ToolTip, il Interfaccia utenteUI del StartPriceEntryForm TextBox simile al seguente quando si verifica un errore di convalida:With the default ErrorTemplate and the ToolTip, the Interfaccia utenteUI of the StartPriceEntryForm TextBox looks like the following when there is a validation error:

Errore di convalida di data bindingData binding validation error

Per un esempio di come fornire una logica di convalida per tutti i controlli in una finestra di dialogo, vedere la sezione Finestre di dialogo personalizzate contenuta in Cenni preliminari sulle finestre di dialogo.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 di convalidaValidation Process

La convalida avviene solitamente quando si trasferisce un valore di destinazione alla proprietà di origine del binding.Validation usually occurs when the value of a target is transferred to the binding source property. Ciò si verifica sul TwoWay e OneWayToSource associazioni.This occurs on TwoWay and OneWayToSource bindings. Come già detto, ciò che fa sì che un aggiornamento dell'origine dipende dal valore della UpdateSourceTrigger proprietà, come descritto nel quali trigger origine aggiornamenti sezione.To reiterate, what causes a source update depends on the value of the UpdateSourceTrigger property, as described in the What Triggers Source Updates section.

Viene di seguito descritto il processo di convalida.The following describes the validation process. Si noti che se in qualsiasi momento durante questo processo si verifica un errore di convalida o un altro tipo di errore, il processo viene interrotto.Note that if a validation error or other type of error occurs at any time during this process, the process is halted.

  1. Il motore di binding controlla se esistono eventuali custom ValidationRule definiti oggetti la cui proprietà ValidationStep è impostata su RawProposedValue tale Binding, nel qual caso chiama il Validate metodo su ogni ValidationRule fino a quando non uno di essi viene rilevato un errore o fino a quando tutti gli elementi passare.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. Il motore di binding chiama quindi il convertitore, se presente.The binding engine then calls the converter, if one exists.

  3. Se il convertitore riesce, il motore di binding controlla se esistono eventuali personalizzato ValidationRule definiti oggetti la cui proprietà ValidationStep è impostata su ConvertedProposedValue tale Binding, nel qual caso chiama il Validate metodo su ogni ValidationRule con ValidationStep impostato su ConvertedProposedValue fino a quando non uno di essi viene rilevato un errore o fino a quando tutti gli elementi passare.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. Il motore di binding imposta la proprietà di origine.The binding engine sets the source property.

  5. Il motore di binding controlla se esistono eventuali personalizzato ValidationRule definiti oggetti la cui proprietà ValidationStep è impostata su UpdatedValue tale Binding, nel qual caso chiama il Validate metodo su ogni ValidationRule con ValidationStep impostata su UpdatedValue fino a quando non uno di essi viene rilevato un errore o fino a quando tutti gli elementi passare.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 un DataErrorValidationRule associata a un'associazione e la relativa ValidationStep è impostata sul valore predefinito, UpdatedValue, il DataErrorValidationRule viene controllato a questo punto.If a DataErrorValidationRule is associated with a binding and its ValidationStep is set to the default, UpdatedValue, the DataErrorValidationRule is checked at this point. Questo è anche il punto quando le associazioni che hanno le ValidatesOnDataErrors impostato su true vengono controllati.This is also the point when bindings that have the ValidatesOnDataErrors set to true are checked.

  6. Il motore di binding controlla se esistono eventuali personalizzato ValidationRule definiti oggetti la cui proprietà ValidationStep è impostata su CommittedValue tale Binding, nel qual caso chiama il Validate metodo su ogni ValidationRule con ValidationStep impostata su CommittedValue fino a quando non uno di essi viene rilevato un errore o fino a quando tutti gli elementi passare.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 un ValidationRule non supera in qualsiasi momento durante questo processo, il motore di binding crea un ValidationError dell'oggetto e lo aggiunge al Errors raccolta dell'elemento associato.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. Viene eseguito prima dell'associazione motore il ValidationRule oggetti in un determinato passaggio, consente di rimuovere qualsiasi ValidationError che è stato aggiunto al Errors collegato proprietà dell'elemento associato durante quel passaggio.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. Ad esempio, se un ValidationRule cui ValidationStep è impostata su UpdatedValue non è riuscita, la volta successiva che si verifica il processo di convalida, il motore di binding rimuove l'oggetto ValidationError immediatamente prima di chiamare ValidationRule dotato ValidationStep impostato su 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 non è vuota, il HasError collegati proprietà dell'elemento è impostata su true.When Errors is not empty, the HasError attached property of the element is set to true. Inoltre, se il NotifyOnValidationError proprietà del Binding è impostata su true, quindi il motore di binding genera il Validation.Error evento sull'elemento associato.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.

Si noti inoltre che un trasferimento di un valore valido in entrambe le direzioni (dalla destinazione all'origine o destinazione) Cancella il Errors proprietà associata.Also note that a valid value transfer in either direction (target to source or source to target) clears the Errors attached property.

Se il binding è un' ExceptionValidationRule associata o se il ValidatesOnExceptions è impostata su true e viene generata un'eccezione quando il motore di binding imposta l'origine, il motore di binding controlla se è presente un 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. È possibile usare il UpdateSourceExceptionFilter callback per fornire un gestore personalizzato per la gestione delle eccezioni.You have the option to use the UpdateSourceExceptionFilter callback to provide a custom handler for handling exceptions. Se un' UpdateSourceExceptionFilter non viene specificato nella Binding, il motore di binding crea un ValidationError con l'eccezione e lo aggiunge al Errors raccolta dell'elemento associato.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.

Meccanismo di debugDebugging Mechanism

È possibile impostare la proprietà associata TraceLevel su un oggetto correlato all'associazione per ricevere informazioni sullo stato di uno specifico binding.You can set the attached property TraceLevel on a binding-related object to receive information about the status of a specific binding.

Vedere ancheSee Also

DataErrorValidationRule
Novità di WPF versione 4.5What's New in WPF Version 4.5
Eseguire l'associazione dei risultati di una query LINQBind to the Results of a LINQ Query
Data bindingData Binding
Demo di Data BindingData Binding Demo
Procedure relative alle proprietàHow-to Topics
Procedura: Eseguire l'associazione a un'origine dati ADO.NETBind to an ADO.NET Data Source