2012-05-18 14 views
5

Quindi, ho una tabella clienti, contenente record clienti, record, ognuno dei quali ha un campo customertipo. Ho anche una tabella customertype, contenente i valori validi per il campo customertype.WPF/XAML - Consentire a ComboBox di avere SelectedValue che non è in ItemsSource

E ho bisogno di un WPF per fare CRUD. (Crea, rivedi, aggiorna, cancella).

La soluzione ovvia è utilizzare un ComboBox, con la proprietà SelectedValue associata al campo customertype e la relativa proprietà ItemsSource associata a un elenco popolato da una query della tabella customertype.

Il problema è che questo non funziona se non nel tipo di semplice problema che si vede negli esercizi.

La difficoltà si pone quando si visualizza o si modifica un record del cliente che ha un valore di tipo di cliente che non è nella tabella del tipo di cliente. Questo può accadere per errore o può accadere perché il tipo di cliente è stato deprecato e rimosso dalla tabella.

In questo caso, WPF deve impostare il campo customertype su null, in quanto SelectedValue non si trova nell'elenco ItemsSource. E questo è un problema.

Se si sta visualizzando solo, è necessario visualizzare il valore presente nella tabella, indipendentemente dal fatto che sia presente nell'elenco. Se stai modificando, puoi fare una ragionevole argomentazione che dovresti anche mostrare il valore che è nella tabella, almeno inizialmente, anche se se cambi la selezione, non puoi ottenere ciò che hai iniziato.

Quindi, qualche idea? Questo è un problema che si verifica praticamente su ogni modulo di modifica/visualizzazione, quindi preferirei qualcosa che sia ragionevolmente pulito al punto di utilizzo. (Cioè, data la scelta della complicazione nello XAML, in ogni caso ho bisogno di gestire uno di questi campi, o complicazione nel codice che supporta il XAML che inserisco per gestire uno di questi campi, preferirei quest'ultimo.)

risposta

3

Per questo, suggerirei di non legare direttamente ItemsSource ai contenuti della tabella CustomerType. Invece, unisci ItemsSource per gli articoli Tipo cliente nelle tabelle Tipo cliente E tutti i valori CustomerType memorizzati nei record Cliente che non esistono nella tabella Tipo cliente. Una volta che l'utente passa dalla visualizzazione alla modifica, aggiorna la raccolta per utilizzare solo quegli elementi nella tabella CustomerType. Quando l'utente entra in modalità di visualizzazione, torna alla raccolta unita.

+0

Ci sto provando e non funziona. Il codice che sta dietro ItemsSource di Combobox ora inserisce l'attuale customerid, se non è in quello che viene restituito dal database, se stiamo visualizzando un record esistente. Ma se cambio per modificare un nuovo record, sto innalzando PropertyChanged sulla proprietà ItemsSource, e nel debugger posso vedere il codice chiamato, e una nuova lista costruita che non include il valore extra, ma nell'interfaccia utente, Vedo ancora la prima lista. –

+0

Hai trie usando ObservableCollection per ItemsSource o INotifyPropertyChanged quando la tua collezione di List cambia? – Josh

+0

Solo un po 'di confusione mentale da parte mia. Non stavo allevando proprietà sulla proprietà che pensavo di essere. –

0

Mentre la risposta di cui sopra serve, garantisce una buona quantità di codice, in ogni caso. E questo problema esiste come schema generale, qualsiasi luogo in cui una lista proviene da un luogo e il valore selezionato viene da un altro.

Non ho ancora deciso una soluzione, ma il mio ultimo tentativo sembra promettere.

Quello che ho fatto è derivare una nuova classe da ComboBox. Ad esso, ho aggiunto una nuova DependencyProperty - AddSelectedIfMissing. E poi sovrascrivo OnItemsChanged(). In esso, controllo se SelectedValue corrisponde al campo SelectedValuePath di uno degli elementi in ItemsSource.

Sono binding ItemsSource a una proprietà del viewmodel che restituisce una raccolta di oggetti record che rappresentano scelte valide. Sto vincolando SelectedValue a una proprietà di viewmodel che contiene il valore esistente. E sto vincolando AddSelectedIfMissing a una proprietà booleana di viewmodel che è vera quando voglio aggiungere il valore Selected a ItemsSource.

E quando cambio da visualizzazione a modifica, sollevo PropertyChanged sulla proprietà associata a ItemsSource, quindi il controllo lo ricaricherà.

Quello che ho ora ha alcune limitazioni. Dipende dall'essere in grado di lanciare ItemsSource da object a IList, e di essere in grado di trasmettere ogni oggetto da un oggetto ad una classe base conosciuta da cui possiamo ottenere valori di campo. E non funzionerebbe se avessi associato SelectedItem, invece di SelectedValue.

Ma entro tali limiti, funziona correttamente.

+1

Puoi pubblicare il tuo codice per questo? Mi rendo conto che è una domanda vecchia, ma ho un problema simile e sarei interessato a questo. – PlTaylor

Problemi correlati