2011-09-29 26 views
5

我有一個自定義控件,它繼承自DataGrid,基本上是一個2D DataGrid(接受ItemsSource有兩個維度,如double[,])。強制WPF數據網格重新生成

我加了一個特定的DependencyProperty這就是ColumnHeadersRowHeaders所以我可以定義它們。

這裏是它如何工作現在:

  • 我綁定一個2D ItemsSourceDataGrid
  • 一個包裝方法,將以此爲源,以將其轉換爲經典IEnumerable綁定到實際的DataGrid的ItemsSource
  • 自動生成的每行/列使用事件AutoGeneratingColumn & AutoGeneratingRow完成以便定義它們的標頭

的問題在這裏:

當我初始化DataGrid,一切工作正常。

在那之後,我的應用程序的使用情況一個規定只有列標題可以改變(通過修改DependencyPropertyColumnHeaders

而且,無論我做什麼在這裏,DataGrid不會再自動生成的列(因此,標題將不會以任何方式改變)

那麼,有沒有辦法要求DataGrid這樣的東西像「嘿,我希望你從頭開始重新啓動並重新生成你的列」?因爲對於現在,我無法到達AutoGeneratingColumn事件,並且調用諸如InvalidateVisual之類的方法只會重新繪製網格(以及不重新生成列)。

這裏的任何想法?

我不知道,我們需要一些代碼,但...我會放一些,所以沒有人問它: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

爲什麼不嘗試重置ItemsSource屬性 –

+0

它的實際工作(我不能相信我還沒有想過,早-__-),但沒有任何「聰明」的方式來做到這一點? – Damascus

+0

@Damascus你是否發現了比取消設置itemssource更聰明的方法?我也在尋找。 – Haozhun

回答

6

重置您的ItemsSource,它應該重新繪製你的DataGrid

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

您還可能能夠刷新綁定,但我還沒有測試,看看這實際上會重新生成的DataGrid:

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

嗨, 刷新將無法正常工作,因爲WPF將首先自動檢查綁定的屬性是否已經發生實際變化(情況並非如此) 重置的itemssource工作正常,但我想知道是否沒有任何「更優雅」的解決方案? – Damascus

3

關閉然後再打開AutogeneratedColumns會導致列自動再次生成。

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

我有一個與OP相似的場景,並且此解決方案比其他解決方案更好。由於某種原因,直接搞亂ItemsSource導致自動生成不起作用。 –