2013-02-27 12 views
6

Sto cercando di creare DataGrid in un UserControl separata il cui DataContext è un elenco di T.WPF DataBinding ObservableCollection <T> al DataGrid

nel codice dietro, creo un elenco, compilare l'elenco, poi inviarlo a il costruttore per UserControl su cui ho il DataGrid che sto cercando di popolare.

La classe UserControl è la seguente.

public partial class QuotePreview : UserControl 
{ 
    private static SelectionList previewList = new SelectionList(); 

    public SelectionList PreviewList 
    { 
     get { return previewList; } 
    } 

    public QuotePreview() 
    { 
     InitializeComponent(); 
    } 

    public QuotePreview(SelectionList selectedOptions) 
    { 
     InitializeComponent(); 

     previewList = selectedOptions; 

     QuotePreviewDataGrid.DataContext = previewList; 
    } 
} 

E il Xaml assomiglia:

<DataGrid Name="QuotePreviewDataGrid" 
      AutoGenerateColumns="False" 
      ItemsSource="{Binding}"> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="Model Number" Binding="{Binding ModelNumber}"/> 
     <DataGridTextColumn Header="Description" Binding="{Binding Description}"/> 
     <DataGridTextColumn Header="List Price per Unit" Binding="{Binding Price}"/> 
    </DataGrid.Columns> 
</DataGrid> 

Ho provato a installare l'ItemSource pure usando

QuotePreviewDataGrid.ItemsSource = PreviewList; 

Ho anche provato a installare sia il contesto dei dati e l'ItemSource così come rinfrescante:

QuotePreviewDataGrid.Items.Refresh(); 

Le assegnazioni di dati che ho impostato su listbox nel resto della mia applicazione funzionano perfettamente. Nelle caselle di riepilogo ho impostato l'origine degli articoli su {Binding} e il binding di ListItems su {Binding Property}. Il datacontext per le listbox impostate nel codice sottostante.

Il mio datagrid qui è impostato nello stesso modo, eppure per qualche motivo non viene visualizzato nulla all'interno della griglia.

Quando si passa attraverso il debugger e si osserva il flusso di informazioni, è possibile visualizzare l'elenco di T, Elenco selezioni creato e passato al costruttore per il controllo utente in cui si trova la griglia di dati. Vedo che DataContext è effettivamente impostato e mostra gli elementi nell'elenco, ma quando torno alla mia appicazione e provo a visualizzare la griglia di dati, è vuoto.

Qualsiasi aiuto sarebbe molto apprezzato. Ho cercato di avvolgere la mia mente su questo problema per l'ultimo giorno e mezzo. Grazie!

UPDATE

Il SelectionList è strutturata come:

public class SelectionList : List<Selection> 
{ 
    public List<Selection> availableSelections = new List<Selection>(); 

    public List<Selection> AvailableSelections 
    { 
     get { return availableSelections; } 
    } 
} 

e una selezione viene poi definita da:

public class Selection : DependencyObject 
{ 
    public bool IsChecked { get; set; } 
    public string ModelNumber { get; set; } 
    public string Description { get; set; } 
    public string Price { get; set; } 
} 

All'avvio dell'applicazione, costruisco un catalogo di esistere prodotti (selezioni). Su diverse schede, una per ogni famiglia di prodotti, il datacontext per la casella di riepilogo prodotti viene inizializzato con i prodotti disponibili che acquisisce dal catalogo. Quindi, in attesa del prodotto selezionato dall'utente, le opzioni disponibili o le selezioni secondarie associate a quel prodotto vengono inserite nelle caselle di riepilogo appropriate, negli accessori e nelle garanzie.

Una volta che l'utente seleziona le opzioni desiderate, viene fatto clic su un pulsante per visualizzare in anteprima gli elementi selezionati che devono compilare la griglia di dati spiegata sopra.

Posso creare l'elenco delle opzioni selezionate, tuttavia quando provo a impostare il contesto dei dati della griglia di dati, non viene visualizzato nulla. Gli elenchi per le selezioni disponibili vengono creati e impostati sul contesto dati appropriato nello stesso modo in cui sto provando a farlo per la griglia di dati, tuttavia la griglia di dati non vuole visualizzare le mie informazioni.

UPDATE

Così, dopo un po 'di debug, ho ristretto il problema un po' giù. L'associazione dati funziona come dovrebbe. Non ho problemi reali lì, non penso. Tuttavia, il problema che sto incontrando ora è quello che ritengo essere 2 diverse istanze del mio controllo utente, ma solo l'originale viene visualizzato, non la copia aggiornata.

Ecco una copia della classe da circa con un paio di righe che ho aggiunto per aiutare a risolvere il problema.

public partial class QuotePreview : UserControl 
{ 
    private SelectionList _selectionList; 
    private SelectionList temp; 

    public QuotePreview() 
    { 
     InitializeComponent(); 
     _selectionList = (SelectionList)this.DataContext; 
    } 

    private void QuotePreview_Loaded(object sender, RoutedEventArgs e) 
    { 
     _selectionList.SelectedOptions.Add(
      new Selection 
      { 
       ModelNumber = "this", 
       Description = "really", 
       Price = "sucks" 
      }); 
    } 

    public QuotePreview(SelectionList selectedOptions) 
    { 
     InitializeComponent(); 
     _selectionList = (SelectionList)this.DataContext; 

     temp = selectedOptions; 

     _selectionList.AddRange(selectedOptions); 

     QuotePreview_Loaded(); 
    } 

    private void QuotePreview_Loaded() 
    { 
     foreach (var options in temp.SelectedOptions) 
     { 
      _selectionList.SelectedOptions.Add(options); 
     } 

     QuotePreviewDataGrid.ItemsSource = _selectionList.SelectedOptions; 
    } 
} 

L'implementazione del costruttore predefinito, viene chiamata ogni volta che si fa clic sul controllo/scheda utente. Quando ciò accade, _selectionList è impostato sul contesto dati del controllo utente, seguito dall'evento Loaded che aggiunge una linea alla mia griglia di dati.

In un altro controllo utente in cui seleziono le opzioni che desidero aggiungere al controllo utente della mia griglia di dati, faccio clic su un pulsante che crea un elenco delle opzioni che desidero aggiungere e chiama il costruttore personalizzato che ho scritto. Una volta che il costruttore termina, chiama un metodo personalizzato di evento caricato che ho creato per merde e risatine, che aggiunge le opzioni selezionate alla mia lista_selezione.

Ora, dopo aver fatto nuovamente clic sul controllo utente della griglia di dati, viene eseguito l'intero processo predefinito e viene aggiunta un'altra riga predefinita.

Se torno indietro una scheda e dico che voglio di nuovo queste opzioni e tornare alla griglia di dati, passa di nuovo attraverso il processo predefinito e aggiunge un'altra linea di default.

La cosa più intrigante è che posso vedere entrambi gli elenchi delle selezioni da quando non ho eliminato i processi intermedi. Vedo un elenco di build delle opzioni che voglio visualizzare e una lista di build delle opzioni predefinite create ...

Oh, anche, SelectionList implementa ObservableCollection.

+0

Significa legare la griglia di dati da elencare, non viceversa. –

+0

Mi chiedo, hai qualche errore di associazione dati nell'output? Se utilizzi Visual Studio, puoi aprire la "Finestra di output" e controllare gli errori di associazione dei dati. se questo non aiuta, prova a usare [Snoop] (http://snoopwpf.codeplex.com/) e vedi se puoi vedere qualche problema lì (puoi ad esempio localizzare il datacontext e vedere di cosa si tratta) e ottenere torna con i risultati – Default

risposta

2

ho finalmente si avvicinò con una soluzione al problema

public static class QuotePreview 
{ 
    public static ObservableCollection<PurchasableItem> LineItems { get; private set; } 

    static QuotePreview() 
    { 
     LineItems = new ObservableCollection<PurchasableItem>(); 
    } 

    public static void Add(List<PurchasableItems> selections) 
    { 
     foreach (var selection in selections) 
     { 
      LineItems.Add(selection); 
     } 
    } 

    public static void Clear() 
    { 
     LineItems.Clear(); 
    } 
} 

public class QuoteTab : TabItem 
{ 
    public ObservableCollection<PurchasableItem> PreviewItems { get; private set; } 

    public QuoteTab() 
    {   
     Initialize() 

     PreviewItems = QuotePreview.LineItems; 

     DataGrid.ItemSource = PreviewItems 
    } 
} 
0

provare a cambiare:

QuotePreviewDataGrid.DataContext = previewList; 

a

this.DataContext = previewList; 

mio sospetto è che il ItemsSource="{Binding}" nel vostro XAML è prevalente il codice DataContext nel costruttore.

Modificando la lista di anteprima come DataContext dell'intero UserControl, l'associazione di DataGrid ItemsSource può essere valutata correttamente.

In una nota a margine, vorrei iniziare a esaminare l'utilizzo di e il modello di progettazione MVVM. Un problema che potresti finire è che il tuo DataGrid non si aggiorna quando l'elenco sottostante cambia, usando lo ObservableCollection<T> risolverà questo problema.

Utilizzando il modello di progettazione MVVM vi darà una buona separazione della logica e dei dati (in questo caso la vostra lista e come è caricato) dal display fisico (DataGrid)

+0

ok, quindi ho provato a fare le modifiche che hai suggerito senza alcun risultato. In realtà avevo già provato l'impostazione this.DataContext = previweList; per escludere questa possibilità. Ho anche cambiato, la PreviewList per essere una ObservableCollection e i miei dati non vengono ancora visualizzati. – Chutes

+0

Possiamo vedere la definizione degli elementi di 'SelectionList'? –

+0

aggiornato in questione sopra – Chutes