Syncfusion WPF DataGrid行移至顶部后选中状态不高亮问题排查
我正在使用Syncfusion WPF DataGrid展示数据,已实现选中行上移、下移、移至顶部和底部的功能。行移动后应保持选中状态,该功能在上移、下移、移至底部时均正常,但移至顶部时选中行无法高亮。
以下是实现移至顶部功能的代码:
public void PriorityMoveTop() { Job? SelectedRow = (Job)this.jobListView.SelectedItem; if (SelectedRow == null) { } else { Job? myJobAfterSelectedRow = (from x in Memory.Jobs where x.Priority == (SelectedRow.Priority - 1) select x).FirstOrDefault(); if (jobListView.SelectedIndex == 0) { } else { foreach (Operation operation in SelectedRow.Operations) { operation.Priority = SelectedRow.Priority; } OrderPriorityColumnDown(); SelectedRow.Priority = 1; } } SetDataGridJobList(); if (SelectedRow == null) { } else { //Code to highlight row jobListView.SelectedIndex = SelectedRow.Priority - 1; } }
用于保持选中行高亮的代码为jobListView.SelectedIndex = SelectedRow.Priority - 1;,请问该代码存在什么问题导致移至顶部时选中行无法高亮?
核心问题出在对象引用一致性和UI更新时机上:
数据源更新后的对象引用失效
调用SetDataGridJobList()后,如果该方法是重新创建了集合实例(而非更新原集合),那么之前的SelectedRow对象已经不是新绑定数据源中的实例。此时通过SelectedIndex = SelectedRow.Priority -1设置选中,可能因为DataGrid无法关联到新数据源中的对应行,导致高亮失效。依赖Priority计算索引的冗余风险
移至顶部后,目标行的索引必然是0,此时用SelectedRow.Priority -1计算完全多余——如果OrderPriorityColumnDown()方法没有正确更新其他行的Priority值,可能导致Priority序列不连续,进而计算出错误的索引。
修复方案
方案一:直接绑定对象实例(推荐)
跳过索引计算,直接从新数据源中找到目标对象并设置选中,这种方式不受索引变化影响,更可靠:
SetDataGridJobList(); if (SelectedRow != null) { // 假设Job有唯一标识Id,通过Id匹配新数据源中的对象 var targetJob = Memory.Jobs.FirstOrDefault(j => j.Id == SelectedRow.Id); if (targetJob != null) { jobListView.SelectedItem = targetJob; // 可选:滚动到选中行确保可见 jobListView.ScrollIntoView(targetJob); } }
方案二:直接设置固定索引
既然移至顶部后目标行一定是第一行,直接设置SelectedIndex=0即可,同时通过Dispatcher确保在UI更新完成后执行:
SetDataGridJobList(); if (SelectedRow != null) { Application.Current.Dispatcher.BeginInvoke(new Action(() => { jobListView.SelectedIndex = 0; })); }
额外检查点
确认OrderPriorityColumnDown()方法正确更新了其他Job的Priority值,保证整个Priority序列是连续且按升序排列的——如果Priority序列混乱,即使选中状态设置正确,DataGrid的行顺序也会不符合预期,导致看起来没选中。
内容的提问来源于stack exchange,提问作者Alessandro

