WPF DataGrid TemplateColumn滚动显示异常问题求助
问题根源与解决方案
这个问题的核心是WPF DataGrid的行虚拟化机制加上你自定义转换器里的索引获取逻辑错误导致的,咱们一步步拆解:
为什么会重复显示0-29?
你开启了EnableRowVirtualization="True"(这也是DataGrid的默认行为),这意味着DataGrid只会创建可见区域内的行容器(也就是你看到的30行),当你滚动时,它会复用这些旧容器来渲染新的数据行,而不是创建新容器。
你的RowCellConverter里用这段代码获取列索引:
int ci = dgcp.ItemContainerGenerator.IndexFromContainer(cell);
但ItemContainerGenerator.IndexFromContainer(cell)返回的是当前单元格容器在可视化树中的位置索引,不是对应数据集合的实际列索引。当容器被复用时,这个值不会随着新数据行的绑定更新,始终停留在0-29的范围内,导致你每次都取到旧行的FieldCell,自然就重复显示了。
而DataGridTextColumn不需要自定义转换器,它直接绑定到当前行的DataContext,所以能正确跟随容器复用更新内容。
怎么修复?
修改RowCellConverter的索引获取逻辑,改用DataGridCell所在列的DisplayIndex来获取对应的FieldCell——这个值是列在DataGrid中的实际顺序索引,和你的cols集合、FieldRow.cells的顺序完全对应,不会因为容器复用而出错。
修改后的Convert方法代码:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { DataGridCell cell = value as DataGridCell; if (cell == null) return null; // 获取当前单元格所在列的索引,这才是对应FieldRow.cells的正确索引 int ci = cell.Column.DisplayIndex; FieldRow fr = cell.DataContext as FieldRow; if (fr == null) return null; object ret = null; switch ((string)parameter) { case "StateColor": ret = fr.cells[ci].StateColor; break; case "MyValue": ret = fr.cells[ci].MyValue; break; default: ret = fr.cells[ci]; break; } return ret; }
额外注意点
- 你的代码里已经设置了
CanUserReorderColumns="False",所以DisplayIndex不会因为用户拖动列而变化,完全匹配你的cols集合顺序,不用额外处理。 - 如果以后需要允许列重排,上面的代码已经是实时获取
DisplayIndex,只要cols和列的顺序对应,就可以正常工作。
内容的提问来源于stack exchange,提问作者Terkosh
相关产品推荐
相关产品推荐

