You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 09:54:05