WPF DataGrid动态列单元格绑定对应MyModelCell数据模型问题咨询
解决方案
实现思路
核心解决逻辑是在动态生成DataGridTemplateColumn时,将当前列对应的列索引存储到列的Tag属性中,再通过多值绑定结合转换器,从当前行(MyModelRow)的Values集合中取出对应索引的MyModelCell实例,作为单元格模板的绑定源。
步骤1:实现多值转换器
创建转换器接收MyModelRow实例和列索引两个参数,返回对应位置的MyModelCell:
using System.Globalization; using System.Windows.Data; public class CellConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length < 2 || values[0] is not MyModelRow row || values[1] is not int columnIndex || columnIndex < 0 || columnIndex >= row.Values.Count) { return null; } return row.Values[columnIndex]; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
步骤2:动态生成绑定列
遍历你的MyModel.Columns集合,逐个生成DataGridTemplateColumn并完成绑定配置:
// 初始化前清空现有列 dataGrid.Columns.Clear(); var cellConverter = new CellConverter(); // 遍历列定义生成对应的DataGrid列 for (int colIndex = 0; colIndex < myModel.Columns.Count; colIndex++) { var currentColumnDef = myModel.Columns[colIndex]; var templateColumn = new DataGridTemplateColumn { Header = currentColumnDef.Header, Tag = colIndex // 存储当前列的索引,核心参数 }; #region 构建只读单元格模板 var cellTemplate = new DataTemplate(); var cellRootFactory = new FrameworkElementFactory(typeof(StackPanel)); // 多值绑定拿到对应的MyModelCell作为根容器的DataContext var cellContextBinding = new MultiBinding { Converter = cellConverter }; cellContextBinding.Bindings.Add(new Binding()); // 绑定当前行的MyModelRow实例 cellContextBinding.Bindings.Add(new Binding("Tag") { RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(DataGridColumn), 1) }); cellRootFactory.SetBinding(FrameworkElement.DataContextProperty, cellContextBinding); // 配置单元格内显示内容,可根据需求自定义 var displayText = new FrameworkElementFactory(typeof(TextBlock)); displayText.SetBinding(TextBlock.TextProperty, new Binding("DisplayValue")); displayText.SetBinding(TextBlock.BackgroundProperty, new Binding("Color")); cellRootFactory.AppendChild(displayText); cellTemplate.VisualTree = cellRootFactory; templateColumn.CellTemplate = cellTemplate; #endregion #region 构建编辑单元格模板(可选) var editTemplate = new DataTemplate(); var editRootFactory = new FrameworkElementFactory(typeof(StackPanel)); editRootFactory.SetBinding(FrameworkElement.DataContextProperty, cellContextBinding); var editBox = new FrameworkElementFactory(typeof(TextBox)); editBox.SetBinding(TextBox.TextProperty, new Binding("CalculatedValue") { UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged }); editRootFactory.AppendChild(editBox); editTemplate.VisualTree = editRootFactory; templateColumn.CellEditingTemplate = editTemplate; #endregion dataGrid.Columns.Add(templateColumn); } // 绑定行数据源 dataGrid.ItemsSource = myModel.Rows;
补充说明
- 如果需要运行时动态增删列,只需监听
MyModel.Columns的CollectionChanged事件,同步重新生成对应列即可。 - 复杂模板可以用XAML字符串+
XamlReader.Parse的方式生成,比FrameworkElementFactory编写更直观,只需提前将转换器加入页面/应用的资源字典即可。
内容的提问来源于stack exchange,提问作者user2190492
相关产品推荐
相关产品推荐

