Telerik WinForms RadGridView SelectionChanging事件遗留部分选中行问题
解决Telerik RadGridView取消SelectionChange后残留选中行的问题
嘿,作为从Web转WinForms的开发者,我太懂这种“类似JS阻止默认行为但没完全生效”的憋屈感了!针对你遇到的RadGridView取消选择后仍有残留选中行的问题,我来分享下实际项目里的解决思路:
问题根源
RadGridView的SelectionChange事件是选中状态已经更新完成后才触发的,这时候你设置e.Cancel = true只能阻止后续的逻辑执行,但控件内部已经完成了部分选中行的更新,所以会出现残留。这和Web里event.preventDefault()阻止默认行为的时机完全不一样——Web里是在动作发生前拦截,而SelectionChange是事后拦截。
最优解决方案:改用SelectionChanging事件
直接换用SelectionChanging事件,它是在选中状态即将变更但还未生效时触发的,这时候设置e.Cancel = true就能彻底阻止选中行的变化,完全不会有残留:
private void radGridView1_SelectionChanging(object sender, GridViewSelectionCancelEventArgs e) { // 检查当前行数据是否已修改 if (IsCurrentRowModified()) { var confirmResult = MessageBox.Show("行数据已修改,是否放弃更改并切换选中行?", "确认提示", MessageBoxButtons.YesNo); if (confirmResult == DialogResult.No) { // 直接阻止选中状态变更,不会有残留 e.Cancel = true; } } } // 你自己的判断数据是否修改的方法 private bool IsCurrentRowModified() { // 这里写你的数据修改判断逻辑,比如对比原始值和当前值 return true; // 示例返回true,根据实际情况修改 }
如果必须用SelectionChange事件的兼容方案
如果因为某些原因不能换事件,那就在事件开头先保存原始选中状态,取消时手动恢复:
private void radGridView1_SelectionChanged(object sender, EventArgs e) { // 第一步:先保存当前变更前的选中行(注意要ToList()复制集合,不然会跟着控件变化) var originalSelectedRows = radGridView1.SelectedRows.ToList(); // 检查数据是否已修改 if (IsCurrentRowModified()) { var confirmResult = MessageBox.Show("行数据已修改,是否放弃更改并切换选中行?", "确认提示", MessageBoxButtons.YesNo); if (confirmResult == DialogResult.No) { e.Cancel = true; // 手动恢复原始选中状态 radGridView1.SelectedRows.Clear(); foreach (var row in originalSelectedRows) { row.IsSelected = true; } // 额外:如果是单行选择,还可以设置CurrentRow回到原来的行 radGridView1.CurrentRow = originalSelectedRows.FirstOrDefault(); } } }
小提示
- 尽量用
SelectionChanging,逻辑更简洁,也避免了手动恢复选中状态的潜在问题; - 保存选中行时一定要用
ToList()或者CopyTo复制集合,不然你拿到的是控件的引用集合,会跟着控件的选中状态一起变化,恢复的时候就无效了。
内容的提问来源于stack exchange,提问作者gilesrpa
相关产品推荐
相关产品推荐

