这是我的 ViewModel 类:
public class ColumnViewModel : ViewModelBase
{
private string bindingPropName;
public string BindingPropName
{
get { return bindingPropName; }
set
{
if (bindingPropName != value)
{
bindingPropName = value;
RaisePropertyChanged("BindingPropName");
}
}
}
private string header;
public string Header
{
get { return header; }
set
{
if (header != value)
{
header = value;
RaisePropertyChanged("Header");
}
}
}
}
DataGrid 扩展类:
public static class DataGridColumns
{
static DataGridColumns()
{
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridTextColumn));
}
private static readonly DependencyProperty DataGridColumnSettingsProperty = DependencyProperty.RegisterAttached(
"DataGridColumnSettings",
typeof(DataGridColumnSettings),
typeof(DataGridColumn));
private static void SetDataGridColumnSettings(DataGridColumn column, DataGridColumnSettings settings) { column.SetValue(DataGridColumnSettingsProperty, settings); }
private static DataGridColumnSettings GetDataGridColumnSettings(DataGridColumn column) { return column.GetValue(DataGridColumnSettingsProperty) as DataGridColumnSettings; }
public static readonly DependencyProperty DisplayColumnsProperty = DependencyProperty.RegisterAttached(
"DisplayColumns",
typeof(IList),
typeof(DataGridColumns),
new PropertyMetadata(null, DisplayColumnsPropertyChanged));
public static void SetDisplayColumns(DataGrid dataGrid, IList columns) { dataGrid.SetValue(DisplayColumnsProperty, columns); }
public static IList GetDisplayColumns(DataGrid dataGrid) { return dataGrid.GetValue(DisplayColumnsProperty) as IList; }
private static void DisplayColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as DataGrid;
var columns = e.NewValue as IList;
var template = GetColumnSettingsTemplate(target);
CreateColumns(target, columns, template);
}
public static readonly DependencyProperty ColumnSettingsTemplateProperty = DependencyProperty.RegisterAttached(
"ColumnSetupTemplate",
typeof(DataTemplate),
typeof(DataGridColumns),
new PropertyMetadata(null, ColumnSettingsTemplateChanged));
public static void SetColumnSettingsTemplate(DataGrid dataGrid, DataTemplate columnSetupTemplate) { dataGrid.SetValue(ColumnSettingsTemplateProperty, columnSetupTemplate); }
public static DataTemplate GetColumnSettingsTemplate(DataGrid dataGrid) { return dataGrid.GetValue(ColumnSettingsTemplateProperty) as DataTemplate; }
private static void ColumnSettingsTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as DataGrid;
var columns = GetDisplayColumns(target);
var template = e.NewValue as DataTemplate;
CreateColumns(target, columns, template);
}
private static void CreateColumns(DataGrid dataGrid, IList columnViewModels, DataTemplate columnSettings)
{
if (dataGrid == null)
return;
dataGrid.Columns.Clear();
if (columnViewModels == null)
return;
foreach (var column in columnViewModels)
{
var newColumn = new DataGridTextColumn();
newColumn.SetValue(FrameworkElement.DataContextProperty, column);
if (columnSettings != null)
{
var settings = columnSettings.LoadContent() as DataGridColumnSettings;
if (settings != null)
{
settings.Setup(newColumn, column);
SetDataGridColumnSettings(newColumn, settings);
}
}
dataGrid.Columns.Add(newColumn);
}
}
}
public class DataGridColumnSettings : FrameworkElement
{
public static readonly DependencyProperty ColumnBindingPathProperty = DependencyProperty.Register(
"ColumnBindingPath",
typeof(string),
typeof(DataGridColumnSettings),
new PropertyMetadata(null, ColumnBindingPathChanged));
public string ColumnBindingPath
{
get { return GetValue(ColumnBindingPathProperty) as string; }
set { SetValue(ColumnBindingPathProperty, value); }
}
private static void ColumnBindingPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var target = d as DataGridColumnSettings;
if (target == null)
return;
target.column.Binding = new Binding(e.NewValue as string);
}
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
"Header",
typeof(object),
typeof(DataGridColumnSettings));
public object Header
{
get { return GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
private DataGridTextColumn column;
private object viewModel;
public void Setup(DataGridTextColumn column, object columnViewModel)
{
this.column = column;
viewModel = columnViewModel;
this.DataContext = columnViewModel;
if (Header is FrameworkElement)
{
(Header as FrameworkElement).DataContext = columnViewModel;
column.Header = Header;
}
else
BindingOperations.SetBinding(column, DataGridColumn.HeaderProperty, new Binding("Header") { Source = this });
column.Binding = new Binding(ColumnBindingPath);
}
}
和我的 XAML 代码:
<DataGrid t:DataGridColumns.DisplayColumns="{Binding Columns}" ItemsSource="{Binding Rows}" AutoGenerateColumns="False">
<t:DataGridColumns.ColumnSettingsTemplate>
<DataTemplate>
<t:DataGridColumnSettings ColumnBindingPath="{Binding BindingPropName}">
<t:DataGridColumnSettings.Header>
<TextBlock Text="{Binding Header}"/>
</t:DataGridColumnSettings.Header>
</t:DataGridColumnSettings>
</DataTemplate>
</t:DataGridColumns.ColumnSettingsTemplate>
</DataGrid>
我想要实现的一切都是添加 CellTemplate:
<DataGrid t:DataGridColumns.DisplayColumns="{Binding Columns}" ItemsSource="{Binding Rows}" AutoGenerateColumns="False">
<t:DataGridColumns.ColumnSettingsTemplate>
<DataTemplate>
<t:DataGridColumnSettings ColumnBindingPath="{Binding BindingPropName}">
<t:DataGridColumnSettings.Header>
<TextBlock Text="{Binding Header}"/>
</t:DataGridColumnSettings.Header>
<t:DataGridColumnSettings.CellTemplate>
<TextBlock Text="{Binding ColumnBindingPath}"/>
</t:DataGridColumnSettings.CellTemplate>
</t:DataGridColumnSettings>
</DataTemplate>
</t:DataGridColumns.ColumnSettingsTemplate>
</DataGrid>
我认为最简单的方法是再添加一个依赖属性来获取单元格模板。然后,如果存在,请在填充 DataGrid 时创建 DataGridTemplateColumn 而不是 DataGridTextColumn,但我在将 CellTemplate TextBlock 绑定到 ColumnBindingPath 依赖属性时遇到了一点问题。请帮忙 ...