2011-09-29 5 views
5

Ho un controllo personalizzato che eredita da DataGrid ed è fondamentalmente un 2D DataGrid (accetta uno ItemsSource con due dimensioni, ad esempio double[,]).Force WPF DataGrid per rigenerarsi

Ho aggiunto uno specifico DependencyProperty che è ColumnHeaders e RowHeaders così posso definirli.

Ecco come funziona in questo momento:

  • ho associare un 2D ItemsSource al DataGrid
  • Metodo involucro avrà questa fonte per trasformarlo in un classico IEnumerable associabile al reale datagrid del ItemsSource
  • Ogni riga/colonna generata automaticamente viene eseguita utilizzando gli eventi AutoGeneratingColumn & AutoGeneratingRow per definire la loro intestazione

Il problema qui:

Quando ho inizializzare il DataGrid, tutto funziona bene.

Dopo di che, uno dei casi d'uso della mia applicazione definisce che solo le intestazioni delle colonne possono cambiare (modificando il DependencyPropertyColumnHeaders

E, ciò che faccio qui, il DataGrid non si ri-AutoGenerate sua colonne (e quindi le intestazioni non saranno modificate in alcun modo)

Quindi, c'è un modo per chiedere allo DataGrid qualcosa come "Ehi, voglio che tu ricominci da zero e rigeneri le tue colonne"? Perché per ora, non riesco a raggiungere l'evento AutoGeneratingColumn e chiamare un metodo come InvalidateVisual ridisegna semplicemente la griglia (e non rigenerare le colonne).

Qualche idea qui?

non sono sicuro che abbiamo bisogno di un po 'di codice, ma ... ci metto un po' in modo che nessuno lo chiede: D

/// <summary> 
    /// IList of String containing column headers 
    /// </summary> 
    public static readonly DependencyProperty ColumnHeadersProperty = 
     DependencyProperty.Register("ColumnHeaders", 
            typeof(IEnumerable), 
            typeof(FormattedDataGrid2D), 
            new PropertyMetadata(HeadersChanged)); 

    /// <summary> 
    /// Handler called when the binding on ItemsSource2D changed 
    /// </summary> 
    /// <param name="source"></param> 
    /// <param name="e"></param> 
    private static void ItemsSource2DPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     FormattedDataGrid2D @this = source as FormattedDataGrid2D; 
     @this.OnItemsSource2DChanged(e.OldValue as IEnumerable, e.NewValue as IEnumerable); 
    } 

     // (in the constructor) 
     AutoGeneratingColumn += new EventHandler<DataGridAutoGeneratingColumnEventArgs>(DataGrid2D_AutoGeneratingColumn); 

    void DataGrid2D_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) 
    { 
     DataGridTextColumn column = e.Column as DataGridTextColumn; 
     column.Header = (ColumnHeaders == null) ? columnIndex++ : (ColumnHeaders as IList)[columnIndex++]; //Header will be the defined header OR the column number 
     column.Width = new DataGridLength(1.0, DataGridLengthUnitType.Auto); 
     Binding binding = column.Binding as Binding; 
     binding.Path = new PropertyPath(binding.Path.Path + ".Value"); // Workaround to get a good value to display, do not take care of that 
    } 
+0

perché non provare a reimpostare la proprietà ItemsSource –

+0

E funziona davvero (e non riesco a credere che non ho pensato che in precedenza -__-), ma c'è un modo "intelligente" per farlo? – Damascus

+0

@Damascus Hai trovato un modo più intelligente di disattivare e impostare originesoggetti? Anche io lo sto cercando. – Haozhun

risposta

6

Cambia la tua ItemsSource e dovrebbe ridisegnare il vostro DataGrid

void ResetDataGrid() 
{ 
    var temp = myDataGrid.ItemsSource; 
    myDataGrid.ItemsSource = null; 
    myDataGrid.ItemsSource = temp; 
} 

si potrebbe anche essere in grado di aggiornare la rilegatura, ma non ho provato per vedere se questo sarà effettivamente rigenerare il DataGrid:

void ResetDataGrid() 
{ 
    myDataGrid.GetBindingExpression(DataGrid.ItemsSourceProperty).UpdateTarget(); 
} 
+0

Ciao, Rinfrescante non funzionerà come WPF verificherà innanzitutto automaticamente se la proprietà bound ha effettivamente cambiato (che non è il caso) Reseting ItemsSource funziona bene, ma mi chiedevo se non c'è alcuna soluzione "più elegante" ? – Damascus

3

La disattivazione e l'attivazione di AutogeneratedColumns determinerà la generazione automatica delle colonne.

dataGrid.AutoGenerateColumns = false; 
dataGrid.AutoGenerateColumns = true; 
+0

Ho uno scenario simile all'OP e questa soluzione ha funzionato meglio dell'altra soluzione. Per qualche ragione, fare confusione con ItemsSource ha causato il mancato funzionamento della generazione automatica. –