Sorting Non-Empty Cells in Silverlight FlexGrid
Sorting is one of the important features of any grid control and C1FlexGrid for Silverlight also supports this feature. You can easily sort C1FlexGrid in the ascending or descending order by clicking on the column headers just by setting the AllowSorting property to true. I came across a requirement where user wanted to sort the grid with the criteria that the empty rows should always be at the bottom and only the non-empty rows get sorted. At first, this seemed a pretty complex task but after implementation, it turned out to be a rather simpler one. The basic idea for this kind of implementation is remove the empty rows from the grid, sort the non-empty rows and append the empty rows at the bottom after the sort operation. Lets quickly go through the implementation step by step.
Capturing the Column
To apply the custom sorting, you need to capture the Column header that is clicked. This can be done in the C1FlexGrid's Click event and get the column using C1FlexGrid's HitTest info. In this event, you also need to set the sort direction info as value for the Tag property of the column.
void c1FlexGrid1_Click(object sender, MouseButtonEventArgs e)
{
var ht = c1FlexGrid1.HitTest(e);
if (ht.CellType == C1.Silverlight.FlexGrid.CellType.ColumnHeader)
{
var col = c1FlexGrid1.Columns[ht.Column];
var sortDirection = (col.Tag is ListSortDirection) && (ListSortDirection)col.Tag == ListSortDirection.Ascending
? ListSortDirection.Descending
: ListSortDirection.Ascending;
col.Tag = sortDirection;
for (int i = 0; i < c1FlexGrid1.Columns.Count; i++)
{
if (i != ht.Column)
c1FlexGrid1.Columns[i].Tag = null;
}
SortColumn(col, sortDirection);
}
c1FlexGrid1.CellFactory = new SortCellFactory();
}
Sorting C1FlexGrid
In the above Click event , you would notice that SortColumn method has been called with 'col' and 'sortDirection' as parameters. This method handles all the operation. We need two List objects with one list containing the empty rows and another one that contains the non-empty rows. Now, the sorting of data needs to be done manually as we can't apply the default sorting. To apply sorting on the list of non-empty rows, you will have to define a Class which inherits the IComparer Interface. Once the non-empty list has been sorted, clear the rows from C1FlexGrid, add rows from the sorted list first followed by rows from the list containing empty rows to the grid.
void SortColumn(Column col, ListSortDirection sortDirection)
{
var list = new List<Row>();
var emptyRows = new List<Row>();
bool isEmptyRow = true;
foreach (var row in c1FlexGrid1.Rows)
{
foreach (var column in c1FlexGrid1.Columns)
{
if (c1FlexGrid1[row.Index, column.Index] == null || c1FlexGrid1[row.Index, column.Index].ToString() == "")
{
isEmptyRow = true;
}
else
{
isEmptyRow = false;
break;
}
}
if (isEmptyRow)
{
emptyRows.Add(row);
}
else
{
list.Add(row);
}
}
list.Sort(new RowComparer(col, sortDirection));
c1FlexGrid1.Rows.Clear();
foreach (var row in list)
{
c1FlexGrid1.Rows.Add(row);
}
foreach (var row in emptyRows)
{
c1FlexGrid1.Rows.Add(row);
}
}
Implementation of the IComparer interface with C1FlexGrid is already explained in this blog. It's for WPF, however it works seamlessly in SilverLight as well. You can even show a sort glyph according to the sort direction of the column using CellFactory. Download C# Sample Download VB Sample Similar implementation can be done in C1FlexGrid for Winforms as well which has been explained in this blog.