2011-09-29 14 views
5

Mam niestandardową kontrolę, która dziedziczy po DataGrid i jest w zasadzie 2D DataGrid (akceptuje ItemsSource z dwoma wymiarami, takimi jak double[,]).Siła WPG DataGrid do regeneracji

Dodałem konkretny DependencyProperty, który jest ColumnHeaders i , więc mogę je zdefiniować.

Oto jak to działa teraz:

  • wiążę 2D ItemsSource do DataGrid
  • Sposób wrapper weźmie tego źródła, aby przekształcić go w klasyczny IEnumerable Bindable na rzeczywisty DataGrid ItemsSource
  • Automatycznie generowany wiersz/kolumna jest wykonywany przy użyciu zdarzeń AutoGeneratingColumn & AutoGeneratingRow w celu zdefiniowania ich nagłówka

Problemem tutaj:

Kiedy zainicjować DataGrid, wszystko działa bez zarzutu.

Po tym, jednym z przypadków użycia mojej aplikacji określa, że ​​tylko nagłówki kolumn można zmieniać (poprzez modyfikację DependencyPropertyColumnHeaders

, a cokolwiek robię Tutaj DataGrid nie będzie ponownie AutoGenerate jego kolumny (iw związku z tym nagłówki nie zostaną w żaden sposób zmienione)

Czy istnieje sposób, aby poprosić o DataGrid coś w rodzaju "Hej, chcę, abyś wznowił od nowa i zregenerował kolumny"? teraz nie mogę osiągnąć zdarzenia AutoGeneratingColumn, a wywołanie metody takiej jak InvalidateVisual spowoduje ponowne rysowanie siatki (i nie regenerować kolumn).

Wszelkie pomysły tutaj?

nie jestem pewien, że potrzebujemy trochę kodu, ale ... Powiem trochę tak nikt nie pyta o to: 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

dlaczego nie spróbować zresetować właściwość ItemsSource –

+0

to rzeczywiście działa (i nie mogę uwierzyć, że nie pomyślał o tym wcześniej -__-), ale czy jest jakiś „mądrzejszy” sposób to zrobić? – Damascus

+0

@Damascus Znalazłeś mądrzejszy sposób niż rozbrajanie i ustawianie itemsource? Ja też tego szukam. – Haozhun

Odpowiedz

6

Zmień ItemsSource i powinna przerysować Twój DataGrid

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

może także być w stanie odświeżyć wiązania, ale nie testowałem go, aby zobaczyć, czy będzie to rzeczywiście zregenerować DataGrid:

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

Witam, Odświeżanie nie działa, ponieważ WPF najpierw sprawdzi automatycznie, czy zmieniona właściwość faktycznie się zmieniła (co nie jest prawdą) Reseting itemssource działa dobrze, ale zastanawiałem się, czy nie ma żadnego "bardziej eleganckiego" rozwiązania ? – Damascus

3

Wyłączenie i wyłączenie autogenerowanych kolumn spowoduje, że kolumny będą automatycznie generowane ponownie.

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

Mam podobny scenariusz do PO i to rozwiązanie działało lepiej niż inne rozwiązanie. Z jakiegoś powodu, bezpośredni kontakt z ItemsSource powodował, że automatyczne generowanie nie działało. –