如何创建支持动态列与单元格模板且兼容虚拟化的DataGrid
DataGrid动态列虚拟化兼容修复方案
将原方法中静态赋值内容的逻辑替换为基于列索引的动态绑定即可解决虚拟化复用导致的内容错乱问题,修改后的核心代码如下:
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { var contentHost = new ContentControl(); // 基于当前列的DisplayIndex构造绑定,直接绑定到DataRowView对应索引的字段 var contentBinding = new Binding($"[{cell.Column.DisplayIndex}]") { Mode = BindingMode.OneWay }; BindingOperations.SetBinding(contentHost, ContentControl.ContentProperty, contentBinding); // 自定义DataTemplate赋值逻辑保持不变 contentHost.ContentTemplate = (DataTemplate)SomeResourceDictionary["SomeResourceKey"]; return contentHost; }
方案说明
- 绑定路径使用
[索引]格式的原因:DataGrid行的默认DataContext就是当前行的DataRowView实例,其索引器可以直接读取对应位置的单元格值,无需额外指定数据源。 - 虚拟化兼容逻辑:当开启虚拟化的单元格被回收复用到其他行时,单元格的DataContext会自动更新为新行的
DataRowView实例,绑定会自动刷新Content属性的值,不会残留旧行的内容,彻底解决滚动时内容错乱的问题。 - 核心需求匹配:
- 动态列绑定:原有基于DataTable的动态数据源方案无需修改,列索引会自动匹配动态生成的列,不需要提前定义字段名称。
- 自定义列模板:每个列可独立指定对应的
DataTemplate赋值给ContentControl,模板内部仅需绑定当前Content的值即可,不需要额外处理列定位逻辑。
如果需要支持单元格编辑功能,对应的GenerateEditingElement方法可以使用完全相同的绑定逻辑,只需要将绑定的Mode调整为BindingMode.TwoWay即可。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

