Grid控件绑定BindingSource时如何正确获取选中行数据?
异常原因
之前直接绑定DataTable时,gridView1.GetRow()方法返回的是DataRowView类型对象,因此强转后取Row属性的逻辑可以正常运行。
当你把数据源换成绑定EmployeeDto集合的BindingSource后,GetRow()返回的直接是EmployeeDto类型的实体对象,不再是DataRowView。此时gridView1.GetRow(selectedRows[i]) as DataRowView的转换结果为null,再访问.Row属性就会触发空引用异常。
对应场景的正确写法
场景1:BindingSource绑定强类型DTO集合(你当前的使用场景)
从你定义的listEmployeeDto命名可以判断,绑定的是EmployeeDto类型的强类型集合,直接将返回值转为对应DTO类型即可,不需要走DataRow的取值逻辑:
private void AddSelectedRowsToList() { var selectedRows = gridView1.GetSelectedRows(); for (var i = 0; i < selectedRows.Length; i++) { var employeeDto = gridView1.GetRow(selectedRows[i]) as EmployeeDto; if (employeeDto == null) continue; string firstName = employeeDto.FirstName; string lastName = employeeDto.LastName; usersInfo.Add(new SAPSUserInfo(firstName, lastName)); } }
场景2:BindingSource包装DataTable作为数据源
如果后续用BindingSource包装DataTable绑定,GetRow()返回的依然是DataRowView,只需要在原有代码基础上增加空判断即可:
private void AddSelectedRowsToList() { var selectedRows = gridView1.GetSelectedRows(); for (var i = 0; i < selectedRows.Length; i++) { var rowView = gridView1.GetRow(selectedRows[i]) as DataRowView; if (rowView == null) continue; var row = rowView.Row; string firstName = row["FirstName"].ToString(); string lastName = row["LastName"].ToString(); usersInfo.Add(new SAPSUserInfo(firstName, lastName)); } }
通用兼容写法
如果不需要强类型访问,也可以直接调用GridView自带的GetRowCellValue方法按列名取值,不需要关心底层数据源是DataTable还是强类型集合,兼容性最好:
private void AddSelectedRowsToList() { var selectedRows = gridView1.GetSelectedRows(); for (var i = 0; i < selectedRows.Length; i++) { int rowHandle = selectedRows[i]; // 过滤新增行、筛选行等非数据行的特殊行 if (rowHandle < 0) continue; string firstName = gridView1.GetRowCellValue(rowHandle, "FirstName")?.ToString(); string lastName = gridView1.GetRowCellValue(rowHandle, "LastName")?.ToString(); if (!string.IsNullOrWhiteSpace(firstName) && !string.IsNullOrWhiteSpace(lastName)) { usersInfo.Add(new SAPSUserInfo(firstName, lastName)); } } }
内容的提问来源于stack exchange,提问作者M.Bouabdallah
相关产品推荐
相关产品推荐

