WinForms中GridView SelectRow方法选中效果不显示问题问询
哈哈,这个坑我踩过!你遇到的问题核心是DevExpress GridView的行选中状态和复选框勾选状态的区别,再加上控件初始化时机不对导致的界面不更新。
问题原因拆解
你用SelectRow(i)设置的是GridView的「行选中状态」——调试时IsRowSelected()返回true就是证明,但界面上的复选框没勾选,分两种情况:
你用的是GridView内置的多选复选框列
也就是已经把gridView1.OptionsSelection.MultiSelect设为true,且MultiSelectMode设为CheckBoxRowSelect的情况。这种模式下,SelectRow()理论上应该同步勾选复选框,但你在构造函数里执行这段代码时机太早了!
构造函数运行时,Form还没完成加载,GridView的可视化组件还没完全初始化,哪怕调用了ForceInitialize(),界面渲染的逻辑还没触发,所以选中状态只是存在内存里,没同步到UI上。你用的是自定义的CheckEdit列
如果复选框是自己添加的GridColumn(列类型设为CheckEdit),那SelectRow()和复选框半毛钱关系都没有——前者是选中整行,后者是对应单元格的值,完全是两个独立的状态。
针对性解决方案
情况1:内置多选复选框列
把选行代码从构造函数移到Form的Load事件,或者GridView的Loaded事件里,等控件完全渲染后再执行:
private void YourForm_Load(object sender, EventArgs e) { gridControl1.DataSource = myObj; gridControl1.ForceInitialize(); for (int i = 0; i < gridView1.DataRowCount; i++) { if (((MyClass)gridView1.GetRow(i)).MyProperty) gridView1.SelectRow(i); } }
如果一定要在构造函数里执行,在代码最后加一句强制刷新:
gridView1.RefreshData();
不过还是推荐用Load事件,更稳妥。
情况2:自定义CheckEdit列
直接设置复选框列对应的单元格值,而不是用SelectRow():
// 假设你的复选框列绑定的字段是IsChecked,或者列名是"CheckColumn" for (int i = 0; i < gridView1.DataRowCount; i++) { var row = (MyClass)gridView1.GetRow(i); if (row.MyProperty) { // 方式1:通过字段名设置 gridView1.SetRowCellValue(i, nameof(MyClass.IsChecked), true); // 方式2:通过列对象设置(如果知道列的话) // gridView1.SetRowCellValue(i, gridColumnCheck, true); } }
额外注意点
- 确认
gridView1.OptionsSelection.MultiSelect是否为true,如果是内置复选框模式,MultiSelectMode必须设为CheckBoxRowSelect; - 如果你的数据源是可绑定的(比如
BindingList<MyClass>),直接修改MyClass的对应属性(比如IsChecked),GridView会自动同步复选框状态,这比手动设置更优雅。
内容的提问来源于stack exchange,提问作者quarandoo

