Domanda

Sto sviluppando un'applicazione WinForms (.Net 3.5, senza WPF) in cui voglio essere in grado di visualizzare le ricerche di chiavi esterne in un DataGridView associato a dati.

Un esempio di questo tipo di relazione è che ho una tabella di OrderLines.Le righe d'ordine hanno una relazione di chiave esterna con i prodotti e i prodotti a loro volta hanno una relazione di chiave esterna con i ProductType.

Mi piacerebbe avere un DataGridView associato a dati in cui ogni riga rappresenta una riga d'ordine, visualizzando il prodotto e il tipo di prodotto della riga.

Gli utenti possono aggiungere o modificare le righe dell'ordine direttamente nella griglia e scegliere il prodotto per la riga dell'ordine da una comboBoxColumn: questa dovrebbe quindi aggiornare la colonna producttype, mostrando il producttype per il prodotto selezionato, nella stessa riga.

La soluzione più vicina a una buona soluzione che ho trovato finora è introdurre un oggetto di dominio che rappresenta una linea d'ordine, quindi associare DataGridView a una raccolta di queste linee d'ordine.Quindi aggiungo proprietà all'oggetto della riga dell'ordine che espongono il prodotto e il tipo di prodotto e sollevo eventi notifypropertychanged pertinenti per mantenere tutto aggiornato.Nel mio repository della riga dell'ordine posso quindi collegare le mappature tra questo oggetto della riga dell'ordine e le tre tabelle nel mio database.

Questo funziona per il lato dell'associazione dati, ma dover codificare manualmente tutta la mappatura OR nel repository sembra negativo.Pensavo che nHibernate sarebbe stato in grado di aiutarmi con questo cablaggio, ma ho difficoltà con le mappature di tutte le chiavi esterne: sembrano funzionare bene (la ricerca con chiave esterna per il prodotto di una riga d'ordine crea l'oggetto prodotto corretto in base alla chiave esterna) finché non prova a eseguire l'associazione dati, non riesco a ottenere che le colonne ID associato ai dati aggiornino il mio prodotto o gli oggetti producttype.

Il mio approccio generale è anche nel campo giusto?Se lo è, qual è una buona soluzione al problema della mappatura?

Oppure esiste una soluzione migliore per l'associazione dati delle righe incluse le ricerche di chiavi esterne che non ho nemmeno preso in considerazione?

È stato utile?

Soluzione

Penso che il problema che stai riscontrando sia che quando ti colleghi a una griglia, non è sufficiente supportare INotifyPropertyChanged, ma devi attivare gli eventi ListChanged nel tuo IBindingList implementazione e assicurati di eseguire l'override e restituire true per il file Supporta ChangeNotification proprietà.Se non restituisci true per questo, la griglia non lo cercherà per sapere se i dati sono cambiati.

In .NET 2.0+ è possibile creare una raccolta generica utilizzando il file .NET 2.0+ BindingList class, questo si occuperà della maggior parte dei problemi (non dimenticare di eseguire l'override e restituire true per la proprietà SupportsChangeNotification).

Se la classe utilizzata per l'associazione dati ha una proprietà che è una raccolta (come IBindingList o BindingList), è possibile associare direttamente la griglia di chiave esterna a tale proprietà.Quando configuri le associazioni nella finestra di progettazione moduli, seleziona semplicemente la proprietà della raccolta come origine dati per la griglia.Dovrebbe "funzionare".L'unica parte subdola è assicurarsi di gestire le raccolte vuote o nulle nel modo giusto.

Altri suggerimenti

benvenuto su StackOverflow :)

Normalmente ciò che faresti è basare le informazioni nel menu a discesa su due valori ValueMember e DisplayMember.

Il ValueMember è l'origine del valore effettivo dei controlli (questo sarà il valore chiave nella riga dell'ordine), il membro di visualizzazione è il valore che viene visualizzato all'utente anziché il valore (questo sarà il valore FK).

Non esiste un motivo particolare per cui non puoi semplicemente restituire tutti i dati richiesti e impostare queste proprietà?

Ecco un buon video "How Do I" che dimostra l'associazione dei dati:

http://windowsclient.net/learn/video.aspx?v=52579

Bene, non so se è supportato da DataGridView, ma quando esegui l'associazione dati WinForms regolare (ad esempio, a una casella di testo normale) puoi utilizzare percorsi di proprietà per navigare attraverso le relazioni tra oggetti.

Qualcosa come questo:

myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber");

Varrebbe la pena vedere se funziona anche nella tua situazione.

Ovviamente la mia domanda iniziale non era chiara, mi dispiace.

Il problema non era con l'associazione dei dati a un DataGridView in generale, o con l'implementazione di un DataGridViewComboBoxColumn - come dicono già giustamente le persone che hanno risposto, che è ben documentato sul web.

Il problema che ho cercato di risolvere riguarda l'aggiornamento delle proprietà che analizzano le relazioni.

Nell'esempio dei miei ordini, quando cambio il valore della colonna "Prodotto", la colonna "Tipo prodotto" non viene aggiornata, anche se nel codice sto impostando la proprietà e attivando l'evento NotifyPropertyChanged.(Nel debug vado in tutti i posti giusti)

Dopo aver riflettuto a lungo, mi sono reso conto che non funzionava nemmeno quando impostavo direttamente la proprietà "Tipo prodotto" dell'origine dati, piuttosto che impostarla nel setter "Prodotto".

L'altra cosa che credo mi riporti sulla strada giusta è che quando fornisco un livello di accesso dati fittizio, creato nel modulo principale, tutto funziona bene.

Inoltre, quando copio l'IList creato da nHibernate in un IBindingList, tutto sembra di nuovo a posto.

COSÌ il problema è che penso che il threading e gli eventi NotifyPropertyChanged vengano persi quando si utilizzano determinate origini dati, in certi modi (vorrei poter essere più definitivo di così!)

Continuerò a cercare modi migliori per risolvere questo problema piuttosto che copiare IList in IBindingList: forse ho bisogno di conoscere il marshalling dei thread.

Modificare

Ora ho sviluppato una soluzione che risolve il problema e penso di capire cosa mi confondeva - in pratica sembra che qualsiasi cosa tranne l'associazione dati di proprietà di base non funzioni bene per gli elenchi che non derivano da BindingList - non appena ci ho provato per associare i dati alle proprietà che hanno attivato eventi NotifyPropertyChanged concatenati, le cose sono andate in tilt e i miei eventi sono andati persi.

La soluzione di accesso ai dati che ho ora utilizza una variante di Rob Conery IRepository pattern, restituendo le mie raccolte da associare come una classe personalizzata che ho creato, una SortableBindingLazyList che deriva da BindingList, implementa i metodi Sort Core e memorizza anche il suo elenco interno come query, ritardando la materializzazione dell'elenco.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top