2011-09-29 17 views
5

Tôi có một điều khiển tùy chỉnh kế thừa từ DataGrid và về cơ bản là 2D DataGrid (chấp nhận ItemsSource với hai thứ nguyên, chẳng hạn như double[,]).Buộc WPF DataGrid tự tái tạo

Tôi đã thêm DependencyProperty cụ thể là ColumnHeadersRowHeaders để tôi có thể xác định chúng.

Sau đây là cách nó hoạt động ngay bây giờ:

  • Tôi gắn một 2D ItemsSource đến DataGrid
  • Một phương pháp wrapper sẽ mất nguồn này để biến nó thành một cổ điển IEnumerable bindable để DataGrid thực tế của ItemsSource
  • Mỗi hàng/cột được tạo tự động được thực hiện bằng các sự kiện AutoGeneratingColumn & AutoGeneratingRow để xác định tiêu đề của chúng

Vấn đề ở đây:

Khi tôi khởi tạo DataGrid, mọi thứ đều hoạt động tốt.

Sau đó, một trong những trường hợp sử dụng các ứng dụng của tôi xác định rằng chỉ có các tiêu đề cột có thể thay đổi (bằng cách sửa đổi DependencyPropertyColumnHeaders

Và, bất cứ điều gì tôi làm ở đây, các DataGrid sẽ không tái AutoGenerate của nó Các cột (và do đó, tiêu đề sẽ không bị thay đổi theo bất kỳ cách nào)

Vì vậy, có cách nào để yêu cầu DataGrid một cái gì đó như "Này, tôi muốn bạn khởi động lại từ đầu và tạo lại cột của bạn"? bây giờ, tôi không thể truy cập sự kiện AutoGeneratingColumn và gọi phương thức như InvalidateVisual sẽ chỉ vẽ lại lưới (và không tạo cột).

Mọi ý tưởng ở đây?

Tôi không chắc rằng chúng ta cần một số mã nhưng ... Tôi sẽ đưa một số để không ai yêu cầu nó: 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

tại sao không thử thiết lập thuộc tính ItemsSource –

+0

Nó thực sự hoạt động (và tôi không thể tin rằng tôi đã không nghĩ về điều đó sớm hơn -__-), nhưng có cách nào "thông minh hơn" để làm điều đó? – Damascus

+0

@Damascus Bạn đã tìm thấy một cách thông minh hơn là xóa và thiết lập các mục nguồn không? Tôi cũng đang tìm kiếm điều đó. – Haozhun

Trả lời

6

Đặt lại ItemsSource của bạn và nó sẽ vẽ lại DataGrid của bạn

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

Bạn cũng có thể có thể làm mới ràng buộc, nhưng tôi đã không kiểm tra nó để xem nếu điều này thực sự sẽ tạo DataGrid:

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

Xin chào, Làm mới sẽ không hoạt động như WPF trước tiên sẽ tự động kiểm tra xem thuộc tính bị ràng buộc có thực sự thay đổi hay không (không phải như vậy) Reseting itemssource hoạt động tốt, nhưng tôi tự hỏi không có giải pháp nào "thanh lịch hơn" ? – Damascus

3

Toggling AutogeneratedColumns tắt và sau đó sẽ làm cho các cột được tự động tạo lại.

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

Tôi có một kịch bản tương tự như OP và giải pháp này làm việc tốt hơn so với giải pháp khác. Đối với một số lý do, trực tiếp rối tung với ItemsSource khiến việc tạo tự động không hoạt động. –