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à ColumnHeaders
và RowHeaders
để 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
đếnDataGrid
- 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ủaItemsSource
- 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 DependencyProperty
ColumnHeaders
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
}
tại sao không thử thiết lập thuộc tính ItemsSource –
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
@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