Just to clarify – the rows in this case are not "selected." Selected refers to the grid's built-in highlighting of rows and there's no connection between that and any individual checkbox column your grid happens to have. That's why the grid.Selected.Rows collection is empty. What you want are the rows that are checked, not selected.
The code Andrew posted above will work in a very simple case, but there are a few caveats. If the users checks the checkbox and the grid and cell they checked still have focus, the Value property of that cell will not be updated, yet. Also, looping through the grid.Rows collection won't work if the grid rows are grouped is using OutlookGroupBy. That code also does not account for filtering presumably you don't want to count rows that are filtered out as checked.
Here's a routine that should work in all of those cases, and is also a bit more efficient, since it does not force the creation of the UltraGridCell objects.
private List GetCheckedRows(UltraGrid grid, string checkBoxColumnKey)
{
// Build a list of checked rows.
var checkedRows = new List();
// Get all of the data rows (ignoring grouping) that arenot filtered out.
var allDataRows = grid.Rows.GetFilteredInNonGroupByRows();
// If a cell is in edit mode, then the Value property will returning the underlying
// value and will not reflect pending changes on the screen that have not yet
// been committed. So see if there's an ActiveCell in edit mode in the checkbox
// column, because if there is, we will need to handle that differently.
var checkBoxColumn = grid.DisplayLayout.Bands[0].Columns[checkBoxColumnKey];
var activeCell = grid.ActiveCell;
bool hasCellInEditMode = null != activeCell &&
0 == string.Compare(activeCell.Column.Key, checkBoxColumnKey, false)&&
activeCell.IsInEditMode;
foreach (var row in allDataRows)
{
bool isRowChecked;
// If there's an active cell in edit mode in the checkbox column
// we need to get it's checked state from the text, not the value, since
// the value is still pending committment.
if (hasCellInEditMode &&
activeCell.Row == row)
{
// Get the text of the cell and parse it to a bool.
// Also, use GetCellText instead of row.Cells["checkBoxColumn"].Text
// because this is more efficient and doesn't force the creation
// of the UltraGridCell object.
isRowChecked = bool.Parse(row.GetCellText(checkBoxColumn));
}
else
{
// GetCellValue instead of row.Cells["checkBoxColumn"].Value
// because this is more efficient and doesn't force the creation
// of the UltraGridCell object.
isRowChecked = (bool)row.GetCellValue(checkBoxColumnKey);
}
// If this row is checked, add it to the list.
if (isRowChecked)
checkedRows.Add(row);
}
// Return the list of all checked rows.
return checkedRows;
}
BTW… while this approach will work and is pretty efficient, it still might take a while to loop through all of the rows. And this approach forces the creation of every row in the grid, so it could take longer the first time you do it. These should only be an issue if you have a tremendous number of rows in your grid.
If that's the case, an alternative approach would be to trap for when the rows are checked and maintain your own list as you go. that way, you never have to loop through all the rows in the grid. But that approach is a bit more complex and, as I said, only makes sense if you have a very large number of rows.