2013-11-27 18 views
5

Sto creando un DataGrid a livello di codice e devo anche supportare ComboBoxColumns.Associazione di un oggetto DataGridComboBoxColumn all'oggetto ItemsGrid di DataGrid in C#

Dopo aver creato DataGrid, ho impostato il numero ItemSource in una raccolta di una serie di tipo BindableList<BindableDictionary>. BindableDictionary è un tipo personalizzato. Ogni BindableDictionary rappresenta una tupla. La chiave è sempre il nome di una colonna e il suo valore è una classe personalizzata che contiene una proprietà generica denominata ActualValue, un Dictionary<T, string> chiamato AllowedValues e uno boolean che determina se AllowedValues verrà utilizzato per creare un ComboBoxColumn o una colonna 'normale'. Anche questa classe implementa INotifyPropertyChanged e INotifyPropertyChanging.

Questa roba funziona, a parte il ComboBoxColumn, duh. Il mio problema con la ComboBoxColumn è che non so come farlo utilizzare l'oggetto AllowedValues di riempire è ITEMLIST e utilizzare la proprietà ActualValue per selezionare la corretta Value dal AllowedValuesBindableDictionary per riempire il textarea.

A titolo di esempio, questo è come mi legano una colonna textbased:

table.Columns.Add(new DataGridTextColumn() { Header = column.GUIName, DisplayIndex = column.Position, Binding = new Binding(column.Name + ".ActualValue") { UpdateSourceTrigger = UpdateSourceTrigger.Default, Mode = BindingMode.TwoWay, NotifyOnTargetUpdated = true, NotifyOnSourceUpdated = true, UpdateSourceExceptionFilter = new UpdateSourceExceptionFilterCallback(BindingExceptionHandler) } }); 

E sì, che funziona.

ho cercato di impostare la proprietà ItemsSource del DataGridComboBoxColumn-column.AllowedValues e impostare il DisplayPath-"Value" che non almeno visualizzare il contenuto corretto, ma non ho idea di come associare alla proprietà ActualValue che è contenuto nel DataGridItemsSource. Ciò significherebbe anche che tutte le celle all'interno di una colonna condividono gli stessi valori selezionabili, il che potrebbe causare problemi in futuro.

E se provo a collegare tutto come ho fatto nello DataGridTextColumn, non viene visualizzato nulla. Inoltre non ci sono elementi da selezionare.

Sarebbe fantastico se qualcuno avesse un suggerimento su cosa potrei provare.

modificare

Appena visto questo: https://stackoverflow.com/a/2197004/937093, ho provato ma poi ho il seguente messaggio nella mia finestra di uscita:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=AllowedValues; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=33493530); target property is 'ItemsSource' (type 'IEnumerable')

Il mio codice è simile al seguente:

col = new DataGridComboBoxColumn() { Header = column.GUIName, SelectedValueBinding = new Binding(column.Name + ".ActualValue"), SelectedValuePath = "ActualValue" }; 
table.Columns.Add(col); 
BindingOperations.SetBinding(col, DataGridComboBoxColumn.ItemsSourceProperty, new Binding("AllowedValues")); 

modifica 2 okay, trovato questo sito web: http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

ho cercato di applicare la roba binding proxy (anche se io non capisco come la Colonna è non parte della struttura visiva del DataGrid ... dove altro sarebbe ?!), ma non funzioneràIl mio codice:

BindingProxy proxy = new BindingProxy() { Data = table.ItemsSource }; 
table.Resources.Add("proxy", proxy }); 
col = new DataGridComboBoxColumn() { Header = column.GUIName, SelectedValueBinding = new Binding("Data." + column.Name + ".ActualValue") { Source = proxy }, DisplayMemberPath = "Value", SelectedValuePath = "Key" }; 
table.Columns.Add(col); 
BindingOperations.SetBinding(col, DataGridComboBoxColumn.ItemsSourceProperty, new Binding("Data." + column.Name + ".AllowedValues") }); 

uscita nella finestra di uscita:

System.Windows.Data Error: 40 : BindingExpression path error: 'MyColumn' property not found on 'object' ''BindingList`1' (HashCode=55207835)'. BindingExpression:Path=Data.MyColumn.ActualValue; DataItem='BindingProxy' (HashCode=45660050); target element is 'TextBlockComboBox' (Name=''); target property is 'SelectedValue' (type 'Object')

Capisco il problema (che sta cercando di trovare l'oggetto 'MyColumn' nel BindingList), ma non capisco il motivo per cui ciò che sta accadendo (dovrebbe risolversi in BindingList [iterator] ["MyColumn"], poiché BindingList contiene BindableDictionary e questo è esattamente ciò che accade per le mie colonne "normali").

risposta

0

Ho fatto qualcosa di simile. Stavo usando Winforms, quindi la mia soluzione potrebbe non funzionare per te. Comunque suggerirei di usare qualcosa di simile a questo.

http://tech.pro/tutorial/776/csharp-tutorial-binding-a-datagridview-to-a-collection

accoppiato con questo.

http://www.codeproject.com/Articles/31418/Implementing-a-Sortable-BindingList-Very-Very-Quic

Come ho avuto tutto funzionare, poi trovato non ho potuto ordinare il mio datagridview.

Non ho il codice sorgente a portata di mano, ma l'idea generale era di creare a mano le mie caselle combinate e le caselle di testo, quindi associare il mio elenco ad esso.

Dopo aver eseguito una funzione che eseguiva l'iterazione su ciascuna riga e in base all'indice (nel mio caso le mie caselle combinate erano le ultime 3 colonne), aggiungerei i valori per la casella combinata a mano prima, quindi dopo quelli sono aggiunti, vorrei controllare il valore della casella combinata e impostarlo.

Ho anche incluso questa funzione nell'evento di errore dati, per quando ho aggiunto una nuova colonna. Inoltre si arresterebbe casualmente se aggiungessi una nuova riga, se avessi il set di autosize. Ho dovuto impostarli su default, fare il mio editing, quindi resettarlo.

Vorrei avere il codice da fornire, ma potrebbe metterti in viaggio. Se no, quando andrò a lavorare domani ne posterò un po '. I combobox sono un enorme problema con cui lavorare.