Condividi tramite


Panoramica del data binding con Windows Forms

In Windows Form è possibile eseguire il binding non solo alle origini dati tradizionali, ma anche a quasi tutte le strutture che contengono dati. È possibile associare un elenco di valori che si calcolano durante l'esecuzione, si leggono da un file o si derivano dai valori di altri controlli.

Inoltre, è possibile associare qualsiasi proprietà di qualsiasi controllo all'origine dati. Nel data binding tradizionale, in genere si associa la proprietà di visualizzazione, ad esempio la proprietà Text di un controllo TextBox, all'origine dati. Con .NET è anche possibile impostare altre proprietà tramite l'associazione. È possibile usare il binding per eseguire le attività seguenti:

  • Impostazione della grafica di un controllo dell'immagine.

  • Impostazione del colore di sfondo di uno o più controlli.

  • Impostazione delle dimensioni dei controlli.

Essenzialmente, il data binding è un modo automatico per impostare qualsiasi proprietà accessibile in fase di esecuzione di qualsiasi controllo in un modulo.

ADO.NET consente di creare molte strutture di dati diverse in base alle esigenze di associazione dell'applicazione e ai dati in uso. È possibile creare classi personalizzate che forniscono o utilizzano dati in Windows Form. Questi oggetti possono offrire diversi livelli di funzionalità e complessità. Dal data binding di base, al supporto in fase di progettazione, al controllo degli errori, alla notifica delle modifiche o anche al supporto per un rollback strutturato delle modifiche apportate ai dati stessi.

Consumatori di interfacce di associazione dati

Le sezioni seguenti descrivono due gruppi di oggetti interfaccia. Il primo gruppo di interfacce viene implementato su origini dati dagli autori delle origini dati. I consumatori dell'origine dati, come i controlli Windows Forms o i componenti, implementano queste interfacce. Il secondo gruppo di interfacce è progettato per l'uso da parte degli autori di componenti. Gli autori di componenti usano queste interfacce quando creano un componente che supporta l'associazione dati da utilizzare dal motore di data binding di Windows Forms. È possibile implementare queste interfacce all'interno delle classi associate al modulo per abilitare il data binding. Ogni caso presenta una classe che implementa un'interfaccia che consente l'interazione con i dati. Gli strumenti per la progettazione dei dati nell'ambito dello sviluppo rapido delle applicazioni (RAD) di Visual Studio sfruttano già questa funzionalità.

Interfacce per l'implementazione dagli autori delle origini dati

I controlli Windows Form implementano le interfacce seguenti:

  • interfaccia IList

    Una classe che implementa l'interfaccia IList può essere un Array, ArrayListo CollectionBase. Questi sono elenchi indicizzati di elementi di tipo Object e gli elenchi devono contenere tipi omogenei, perché il primo elemento dell'indice determina il tipo. IList sarebbe disponibile per il collegamento solo in fase di esecuzione.

    Annotazioni

    Se si desidera creare un elenco di oggetti business per l'associazione con Windows Form, è consigliabile usare il BindingList<T>. Il BindingList è una classe estendibile che implementa le interfacce primarie necessarie per il data binding bidirezionale di Windows Form.

  • interfaccia IBindingList

    Una classe che implementa l'interfaccia IBindingList offre un livello molto superiore di funzionalità di data binding. Questa implementazione offre funzionalità di ordinamento di base e notifica delle modifiche. Entrambi sono utili quando cambiano gli elementi dell'elenco e quando l'elenco stesso cambia. La notifica delle modifiche è importante se si prevede di associare più controlli agli stessi dati. Consente di apportare modifiche ai dati apportate in uno dei controlli da propagare agli altri controlli associati.

    Annotazioni

    La notifica di modifica è abilitata per l'interfaccia IBindingList tramite la proprietà SupportsChangeNotification che, quando true, genera un evento ListChanged, che indica l'elenco modificato o un elemento nell'elenco modificato.

    Il tipo di modifica viene descritto dalla proprietà ListChangedType del parametro ListChangedEventArgs. Di conseguenza, ogni volta che il modello di dati viene aggiornato, verranno aggiornate anche tutte le viste dipendenti, ad esempio altri controlli associati alla stessa origine dati. Tuttavia, gli oggetti contenuti nell'elenco dovranno notificare all'elenco quando cambiano in modo che l'elenco possa generare l'evento ListChanged.

    Annotazioni

    Il BindingList<T> fornisce un'implementazione generica dell'interfaccia IBindingList.

  • interfaccia IBindingListView

    Una classe che implementa l'interfaccia IBindingListView fornisce tutte le funzionalità di un'implementazione di IBindingList, insieme alla funzionalità di filtro e ordinamento avanzato. Questa implementazione offre filtri basati su stringhe e l'ordinamento di più colonne con coppie di descrittori di proprietà.

  • interfaccia IEditableObject

    Una classe che implementa l'interfaccia IEditableObject consente a un oggetto di controllare quando le modifiche apportate a tale oggetto vengono rese permanenti. Questa implementazione supporta i metodi BeginEdit, EndEdite CancelEdit, che consentono di eseguire il rollback delle modifiche apportate all'oggetto. Di seguito è riportata una breve spiegazione del funzionamento dei metodi BeginEdit, EndEdite CancelEdit e come funzionano tra loro per abilitare un possibile rollback delle modifiche apportate ai dati:

    • Il metodo BeginEdit segnala l'inizio di una modifica in un oggetto . Un oggetto che implementa questa interfaccia dovrà archiviare gli aggiornamenti dopo la chiamata al metodo BeginEdit in modo che gli aggiornamenti possano essere eliminati se viene chiamato il metodo CancelEdit. In Windows Forms di data binding è possibile chiamare BeginEdit più volte nell'ambito di una singola transazione di modifica (ad esempio, BeginEdit, BeginEdit, EndEdit). Le implementazioni di IEditableObject devono tenere traccia del fatto che BeginEdit sia già stato chiamato e ignorare le chiamate successive a BeginEdit. Poiché questo metodo può essere chiamato più volte, è importante che le chiamate successive a esso non siano distruttive. Le successive BeginEdit chiamate non possono eliminare definitivamente gli aggiornamenti eseguiti o modificare i dati salvati nella prima chiamata BeginEdit.

    • Il metodo EndEdit invia le modifiche fatte dopo che BeginEdit è stato chiamato all'interno dell'oggetto sottostante, se l'oggetto è in modalità di modifica.

    • Il metodo CancelEdit elimina tutte le modifiche apportate all'oggetto .

    Per altre informazioni sul funzionamento dei metodi di BeginEdit, EndEdite CancelEdit, vedere Salvare nuovamente i dati nel database.

    Questa nozione transazionale di funzionalità dei dati viene usata dal controllo DataGridView.

  • interfaccia ICancelAddNew

    Una classe che implementa l'interfaccia ICancelAddNew implementa in genere l'interfaccia IBindingList e consente di eseguire il rollback di un'aggiunta apportata all'origine dati con il metodo AddNew. Se la tua origine dati implementa l'interfaccia IBindingList, dovresti farle implementare anche l'interfaccia ICancelAddNew.

  • interfaccia IDataErrorInfo

    Una classe che implementa l'interfaccia IDataErrorInfo consente agli oggetti di offrire informazioni sugli errori personalizzate ai controlli associati:

    • La proprietà Error restituisce il testo generale del messaggio di errore , ad esempio "Si è verificato un errore".

    • La proprietà Item[] restituisce una stringa con il messaggio di errore specifico della colonna , ad esempio "Il valore nella colonna State non è valido".

  • interfaccia IEnumerable

    Una classe che implementa l'interfaccia IEnumerable viene in genere utilizzata da ASP.NET. Il supporto di Windows Form per questa interfaccia è disponibile solo tramite il componente BindingSource.

    Annotazioni

    Il componente BindingSource copia tutti gli elementi IEnumerable in un elenco separato a scopo di associazione.

  • interfaccia ITypedList

    Una classe di raccolte che implementa l'interfaccia ITypedList offre la possibilità di controllare l'ordine e l'insieme delle proprietà esposte al controllo collegato.

    Annotazioni

    Quando si implementa il metodo GetItemProperties e l'array PropertyDescriptor non è null, l'ultima voce nell'array sarà il descrittore di proprietà che descrive la proprietà di elenco che è un altro elenco di elementi.

  • interfaccia ICustomTypeDescriptor

    Una classe che implementa l'interfaccia ICustomTypeDescriptor fornisce informazioni dinamiche su se stessa. Questa interfaccia è simile a ITypedList ma viene usata per gli oggetti anziché per gli elenchi. Questa interfaccia viene usata da DataRowView per proiettare lo schema delle righe sottostanti. Una semplice implementazione di ICustomTypeDescriptor viene fornita dalla classe CustomTypeDescriptor.

    Annotazioni

    Per supportare l'associazione in fase di progettazione ai tipi che implementano ICustomTypeDescriptor, il tipo deve implementare anche IComponent ed esistere come istanza nel form.

  • interfaccia IListSource

    Una classe che implementa l'interfaccia IListSource abilita l'associazione basata su elenco su oggetti non elenco. Il metodo GetList di IListSource viene utilizzato per restituire un elenco associabile da un oggetto che non eredita da IList. IListSource viene usato dalla classe DataSet.

  • interfaccia IRaiseItemChangedEvents

    Una classe che implementa l'interfaccia IRaiseItemChangedEvents è un elenco associabile che implementa anche l'interfaccia IBindingList. Questa interfaccia viene utilizzata per indicare se il tipo genera eventi ListChanged di tipo ItemChanged tramite la relativa proprietà RaisesItemChangedEvents.

    Annotazioni

    È consigliabile implementare il IRaiseItemChangedEvents se l'origine dati fornisce la proprietà per elencare la conversione di eventi descritta in precedenza e interagisce con il componente BindingSource. In caso contrario, il BindingSource eseguirà anche la proprietà per elencare la conversione degli eventi con prestazioni più lente.

  • interfaccia ISupportInitialize

    Un componente che implementa l'interfaccia ISupportInitialize sfrutta i vantaggi delle ottimizzazioni batch per l'impostazione delle proprietà e l'inizializzazione delle proprietà co-dipendenti. Il ISupportInitialize contiene due metodi:

    • BeginInit segnala l'avvio dell'inizializzazione degli oggetti.

    • EndInit segnala che l'inizializzazione degli oggetti sta terminando.

  • interfaccia ISupportInitializeNotification

    Un componente che implementa l'interfaccia ISupportInitializeNotification implementa anche l'interfaccia ISupportInitialize. Questa interfaccia consente di notificare ad altri componenti ISupportInitialize che l'inizializzazione è stata completata. L'interfaccia ISupportInitializeNotification contiene due membri:

  • interfaccia INotifyPropertyChanged

    Una classe che implementa questa interfaccia è un tipo che genera un evento quando uno dei relativi valori di proprietà cambia. Questa interfaccia è progettata per sostituire il modello di presenza di un evento di modifica per ogni proprietà di un controllo. Se usato in un BindingList<T>, un oggetto business deve implementare l'interfaccia INotifyPropertyChanged e la BindingList`1 convertirà gli eventi PropertyChanged in eventi di ListChanged di tipo ItemChanged.

    Annotazioni

    Affinché la notifica delle modifiche avvenga in un'associazione tra un client associato e un'origine dati, il tipo di origine dati associato dovrebbe implementare l'interfaccia INotifyPropertyChanged (preferita), oppure è possibile fornire eventi propertyNameChanged per il tipo associato, ma non si dovrebbero eseguire entrambe le operazioni.

Interfacce per l'implementazione da parte degli autori di componenti

Le interfacce seguenti sono progettate per l'utilizzo da parte del motore di data binding di Windows Form:

  • interfaccia IBindableComponent

    Una classe che implementa questa interfaccia è un componente non di controllo che supporta il data binding. Questa classe restituisce i data binding e il contesto di associazione del componente tramite le proprietà DataBindings e BindingContext di questa interfaccia.

    Annotazioni

    Se il componente eredita da Control, non è necessario implementare l'interfaccia IBindableComponent.

  • interfaccia ICurrencyManagerProvider

    Una classe che implementa l'interfaccia ICurrencyManagerProvider è un componente che fornisce il proprio CurrencyManager per gestire le associazioni associate a questo particolare componente. L'accesso al CurrencyManager personalizzato viene fornito dalla proprietà CurrencyManager.

    Annotazioni

    Una classe che eredita da Control gestisce automaticamente le associazioni tramite la relativa proprietà BindingContext, pertanto i casi in cui è necessario implementare il ICurrencyManagerProvider sono piuttosto rari.

Sorgenti dati supportate da Windows Forms

Tradizionalmente, il data binding è stato usato all'interno delle applicazioni per sfruttare i vantaggi dei dati archiviati nei database. Con il data binding di Windows Form, è possibile accedere ai dati da database e dati in altre strutture, ad esempio matrici e raccolte, purché siano stati soddisfatti determinati requisiti minimi.

Strutture da legare a

In Windows Forms è possibile eseguire l'associazione a un'ampia gamma di strutture, da oggetti semplici (associazione semplice) a elenchi complessi, ad esempio tabelle di dati ADO.NET (associazione complessa). Per l'associazione semplice, Windows Forms supporta l'associazione alle proprietà pubbliche di un oggetto semplice. L'associazione basata sull'elenco di Windows Form richiede in genere che l'oggetto supporti l'interfaccia IList o l'interfaccia IListSource. Inoltre, se ti associ tramite un componente BindingSource, puoi associarti a un oggetto che supporta l'interfaccia IEnumerable.

L'elenco seguente mostra gli elementi a cui è possibile collegarsi in Windows Forms.

  • BindingSource

    Un BindingSource è la fonte di dati più comune per Windows Forms e funge da proxy tra una fonte di dati e i controlli di Windows Forms. Il modello di utilizzo generale BindingSource consiste nell'associare i controlli al BindingSource e associare l'BindingSource all'origine dati, ad esempio una tabella dati ADO.NET o un oggetto business. Il BindingSource fornisce servizi che permettono e ottimizzano il livello di supporto per il data binding. Ad esempio, i controlli di Windows Form basati su elenchi, come DataGridView e ComboBox, non supportano direttamente l'associazione a origini dati IEnumerable; tuttavia, è possibile abilitare questo scenario tramite un'associazione mediante un BindingSource. In questo caso, il BindingSource convertirà l'origine dati in un IList.

  • Oggetti semplici

    Windows Forms supporta l'associazione delle proprietà dei controlli alle proprietà pubbliche su un'istanza di un oggetto utilizzando il tipo Binding. Windows Forms supportano anche controlli basati su elenchi associativi, come un ListControl a un'istanza di un oggetto quando viene utilizzato un BindingSource.

  • Matrice o raccolta

    Per fungere da origine dati, un elenco deve implementare l'interfaccia IList; un esempio è una matrice che è un'istanza della classe Array. Per altre informazioni sulle matrici, vedere Procedura: Creare una matrice di oggetti (Visual Basic).

    In generale, è consigliabile usare BindingList<T> quando si creano elenchi di oggetti per il data binding. BindingList è una versione generica dell'interfaccia IBindingList. L'interfaccia IBindingList estende l'interfaccia IList aggiungendo proprietà, metodi ed eventi necessari per il data binding bidirezionale.

  • IEnumerable

    I controlli Windows Form possono essere associati a origini dati che supportano l'interfaccia IEnumerable solo se sono associati tramite un componente BindingSource.

  • Oggetti di dati ADO.NET

    ADO.NET fornisce molte strutture di dati adatte per l'associazione. Ognuno varia nella sua sofisticazione e complessità.

    • DataColumn

      Un DataColumn è l'elemento costitutivo essenziale di un DataTable, dato che più colonne costituiscono una tabella. Ogni DataColumn ha una proprietà DataType che determina il tipo di dati che la colonna contiene, ad esempio la marca di un'automobile in una tabella che descrive le automobili. È possibile associare in modo semplice un controllo, ad esempio la proprietà TextBox di un controllo Text, a una colonna all'interno di una tabella dati.

    • DataTable

      Un DataTable è la rappresentazione di una tabella, con righe e colonne, in ADO.NET. Una tabella di dati contiene due raccolte: DataColumn, che rappresenta le colonne di dati in una determinata tabella (che determina infine i tipi di dati che possono essere immessi in tale tabella) e DataRow, che rappresenta le righe di dati in una determinata tabella. È possibile associare in modo complesso un controllo alle informazioni contenute in una tabella dati, ad esempio associare il controllo DataGridView a una tabella dati. Tuttavia, quando si effettua il binding a un DataTable, si fa riferimento alla visualizzazione predefinita della tabella.

    • DataView

      Un DataView è una vista personalizzata di una singola tabella dati che può essere filtrata o ordinata. Una vista dati è l'istantanea dei dati utilizzata dai controlli complessi associati. È possibile effettuare un legame semplice o complesso ai dati all'interno di una visualizzazione dati, ma si noti che si sta effettuando il legame a un'istantanea dei dati anziché a una sorgente dati sempre aggiornata.

    • DataSet

      Un DataSet è una raccolta di tabelle, relazioni e vincoli dei dati in un database. È possibile associare in modo semplice o complesso ai dati all'interno di un dataset, ma si noti che state effettuando il binding al DataViewManager predefinito per il DataSet (vedere il punto elenco successivo).

    • DataViewManager

      Un DataViewManager è una visualizzazione personalizzata dell'intera DataSet, analoga a una DataView, ma con le relazioni incluse. Con una raccolta DataViewSettings, è possibile impostare i filtri e le opzioni di ordinamento predefiniti per qualunque visualizzazione che DataViewManager ha per una determinata tabella.

Tipi di data binding (associazione dati)

Windows Form può sfruttare due tipi di data binding: binding semplice e binding complesso. Ognuno offre vantaggi diversi.

Tipo di associazione dati Descrizione
Data binding semplice La capacità di un controllo di associarsi a un singolo elemento dati, come un valore in una colonna di una tabella di un set di dati. Il data binding semplice è il tipo di associazione tipico per i controlli, ad esempio un controllo TextBox o un controllo Label, che sono controlli che in genere visualizzano solo un singolo valore. In effetti, qualsiasi proprietà di un controllo può essere associata a un campo in un database. È disponibile un ampio supporto per questa funzionalità in Visual Studio.

Per ulteriori informazioni, vedere Navigare nei dati e Creare un controllo a semplice associazione (Windows Forms .NET).
Associazione dati complessa Possibilità di un controllo di eseguire l'associazione a più elementi dati, in genere più di un record in un database. L'associazione complessa è detta anche associazione basata su elenco. Esempi di controlli che supportano l'associazione complessa sono i controlli DataGridView, ListBoxe ComboBox. Per un esempio di data binding complesso, vedere come associare un controllo ComboBox o ListBox di Windows Forms ai dati.

Componente di associazione di origine

Per semplificare il data binding, i Windows Forms consentono di associare un'origine dati al componente BindingSource e di conseguenza associare i controlli al BindingSource. È possibile usare il BindingSource in scenari di binding semplici o complessi. In entrambi i casi, il BindingSource funge da intermediario tra l'origine dati e i controlli associati, fornendo notifiche di modifica, gestione della valuta e altri servizi.

Scenari comuni che usano il data binding

Quasi ogni applicazione commerciale usa informazioni lette da origini dati di un tipo o un'altra, in genere tramite il data binding. L'elenco seguente mostra alcuni degli scenari più comuni che utilizzano il data binding come metodo di presentazione e manipolazione dei dati.

Sceneggiatura Descrizione
Rendicontazione I report offrono un modo flessibile per visualizzare e riepilogare i dati in un documento stampato. È comune creare un report che visualizza e stampa il contenuto selezionato di una sorgente di dati sullo schermo o su una stampante. I report comuni includono elenchi, fatture e riepiloghi. Gli elementi vengono formattati in colonne di elenchi, con elementi secondari organizzati in ogni voce di elenco, ma è consigliabile scegliere il layout più adatto ai dati.
Immissione di dati Un modo comune per immettere grandi quantità di dati correlati o richiedere informazioni agli utenti consiste nell'usare un modulo di immissione dati. Gli utenti possono immettere informazioni o selezionare opzioni usando caselle di testo, pulsanti di opzione, elenchi a discesa e caselle di controllo. Le informazioni vengono quindi inviate e archiviate in un database, la cui struttura è basata sulle informazioni immesse.
Relazione principale/dettaglio Un'applicazione principale/dettaglio è un formato per esaminare i dati correlati. In particolare, sono presenti due tabelle di dati con una relazione che si connette nell'esempio aziendale classico, una tabella "Customers" e una tabella "Orders" con una relazione tra i clienti e i rispettivi ordini. Per altre informazioni sulla creazione di un'applicazione master/dettaglio con due controlli Windows Form, vedere DataGridView.
Tabella di ricerca Un altro scenario comune di presentazione/manipolazione dei dati è la ricerca di tabelle. Spesso, come parte di una visualizzazione di dati di dimensioni maggiori, viene usato un controllo ComboBox per visualizzare e modificare i dati. La chiave è che i dati visualizzati nel controllo ComboBox sono diversi dai dati scritti nel database. Ad esempio, se si dispone di un controllo ComboBox che visualizza gli articoli disponibili da un negozio di alimentari, è probabile che si vogliano visualizzare i nomi dei prodotti (pane, latte, uova). Tuttavia, per semplificare il recupero delle informazioni all'interno del database e per la normalizzazione del database, è probabile che le informazioni per gli elementi specifici di un determinato ordine siano archiviati come numeri di elemento (#501, #603 e così via). Pertanto, esiste una connessione implicita tra il "nome descrittivo" del prodotto alimentare nel controllo ComboBox sul tuo modulo e il numero di articolo correlato presente in un ordine. È l'essenza di una ricerca in tabella. Per altre informazioni, vedere Procedura: Creare una tabella di ricerca con il componente BindingSource di Windows Forms.

Vedere anche