求助:dataGridView.FirstDisplayedScrollingRowIndex失效,滚动条无法定位至最后一行
解决DataGridView滚动条定位到最后一行却被RowStateChanged事件重置的问题
我完全懂你碰到的这个坑——本来想通过dataGridView.FirstDisplayedScrollingRowIndex = dataGridView.SelectedRows[0].Index;把滚动条定位到目标行(比如最后一行),结果刚设置完,RowStateChanged事件就把这个值给重置了,导致设置完全没生效。这本质是控件内部的状态更新逻辑和你的代码执行顺序冲突了,下面给你几个靠谱的解决思路:
方法1:用BeginInvoke延迟执行设置
把你的滚动条定位代码放到BeginInvoke里,让它在UI线程的消息队列末尾执行,等RowStateChanged这类内部事件处理完再生效,就不会被覆盖了:
// 替换原来的单行设置代码 dataGridView.BeginInvoke(new Action(() => { // 先判断选中行是否存在,避免空引用异常 if (dataGridView.SelectedRows.Count > 0) { dataGridView.FirstDisplayedScrollingRowIndex = dataGridView.SelectedRows[0].Index; } }));
方法2:在RowStateChanged事件中补全设置(带防循环判断)
如果你必须保留RowStateChanged事件的逻辑,可以在事件里重新设置滚动条位置,但一定要加判断条件,防止无限触发事件:
private void dataGridViewActivity_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e) { // 仅当目标行和当前显示的首行不一致时才更新 if (dataGridView.SelectedRows.Count > 0 && dataGridView.FirstDisplayedScrollingRowIndex != dataGridView.SelectedRows[0].Index) { dataGridView.FirstDisplayedScrollingRowIndex = dataGridView.SelectedRows[0].Index; } }
方法3:直接定位到最后一行(如果需求明确)
如果你的需求就是固定定位到最后一行,不用依赖选中行,可以直接这么写,逻辑更简单:
// 确保数据已经加载完成,Rows.Count不为0 if (dataGridView.Rows.Count > 0) { dataGridView.FirstDisplayedScrollingRowIndex = dataGridView.Rows.Count - 1; }
额外注意事项
- 一定要确保你的定位代码是在数据绑定完成后执行的,比如放在
DataBindingComplete事件里,要是数据还没加载完就设置,肯定会无效。 - 任何时候访问
SelectedRows都要先判断Count > 0,避免空引用报错。
内容的提问来源于stack exchange,提问作者Nirav Parsana
相关产品推荐
相关产品推荐

