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

WPF DataGrid滚动时行头自定义箭头重复显示问题

问题根因

WPF DataGrid默认开启UI虚拟化机制,当数据量超出可视区域生成垂直滚动条时,DataGrid不会为全量数据创建持久化的DataGridRow行容器,仅维护可视区域范围内的行实例,滚动过程中会反复复用这些行容器渲染不同索引的数据。
你当前的实现直接为GetRow方法返回的单个行容器实例设置箭头Header,当这个行容器被滚动事件触发复用来渲染其他行数据时,之前设置的箭头不会被自动清除,最终出现箭头每隔数行重复显示的现象,和行定位方法的效率无关。

修复方案

不要直接操作单次获取的行容器实例,改为在DataGrid.LoadingRow事件中动态判断行索引、设置Header,确保行容器复用时非起始行的Header会被主动清空,避免样式残留。

  • 新增类级别属性存储当前导入起始行索引,调整起始点时同步更新该属性即可
  • 为DataGrid注册LoadingRow事件,每次行容器加载/复用时根据当前行的真实索引判断是否显示箭头
  • 移除原有直接给行实例设置Header的逻辑,更新起始行后调用Items.Refresh()触发行重新加载即可

修正后的代码

起始行属性定义

' 替换原有SetStartingRowArrowHeader里的临时startingRow变量
Private _currentStartImportRow As Integer
Public Property CurrentStartImportRow As Integer
    Get
        Return _currentStartImportRow
    End Get
    Set(value As Integer)
        _currentStartImportRow = value
        ' 刷新列表触发行重新加载,更新箭头显示
        dgExcelDataGrid.Items.Refresh()
        RaiseCanShiftStartingRowCommandChanged()
    End Set
End Property

DataGrid行加载事件(在窗口初始化/导入Excel前注册一次即可)

' 注册事件,不要重复注册
AddHandler dgExcelDataGrid.LoadingRow, AddressOf DgExcelDataGrid_LoadingRow

Private Sub DgExcelDataGrid_LoadingRow(sender As Object, e As DataGridRowEventArgs)
    Dim currentRow As DataGridRow = e.Row
    ' 获取当前行容器绑定的真实数据索引,虚拟化场景下不要用行容器自带的GetIndex方法,会出现索引不准的问题
    Dim realRowIndex As Integer = dgExcelDataGrid.Items.IndexOf(currentRow.Item)
    
    If realRowIndex = CurrentStartImportRow Then
        Dim arrowIcon = New FontAwesome.WPF.ImageAwesome()
        arrowIcon.Icon = FontAwesome.WPF.FontAwesomeIcon.ArrowCircleOutlineRight
        arrowIcon.Width = 15
        arrowIcon.Height = 15
        arrowIcon.Foreground = Brushes.Blue
        currentRow.Header = arrowIcon
    Else
        ' 非起始行必须清空Header,避免容器复用导致箭头残留
        currentRow.Header = Nothing
    End If
End Sub

修正后的起始行设置方法

Private Sub SetStartingRowArrowHeader()
    Dim _window = TryCast(Me.NotifyWindow, Import)
    dgExcelDataGrid = _window.dgExcelDataGrid
    ' 仅更新起始行属性,自动触发列表刷新
    CurrentStartImportRow = ExcelSheetTypeSelected.Start_Import_Row
End Sub

补充说明

原有的GetRow扩展方法可以保留,其他需要临时操作可视行的场景仍可正常使用,仅不适合用来设置需要持久生效的行样式、行内容这类受虚拟化复用影响的属性。


内容的提问来源于stack exchange,提问作者Mohamad Hammash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:45:43