DataGridView: sort by one type of data first

165 Views Asked by At

I have a DataGridView that I populate with a file and folder list. I'd like to sort the DataGridView alphabetically, but with all the folders above the files. Here's the general idea:

.\folder1\
.\folder2\
.\folder3\
.\file1
.\file2

I have a column with icons for the different filetypes, so there's a folder icon and file icons. It's the only difference I have between the two columns. Here's a picture: enter image description here

So you can see that files and folders have different icons. Here is my current sort method:

private void dgvFiles_SortCompare(object sender, DataGridViewSortCompareEventArgs e) {
    if(e.Column.Index == 1) {
        // ???
    }
    else if(e.Column.Index == 4) {
        string cellValue1 = e.CellValue1.ToString(),
        cellValue2 = e.CellValue2.ToString();

        if(!string.IsNullOrWhiteSpace(cellValue1) && !string.IsNullOrWhiteSpace(cellValue2)) {
            cellValue1 = Regex.Replace(cellValue1, "[^.0-9]", "");
            cellValue2 = Regex.Replace(cellValue2, "[^.0-9]", "");

            int a = int.Parse(cellValue1), b = int.Parse(cellValue2);

            e.SortResult = a.CompareTo(b);

            e.Handled = true;
        }
    }
}

Is it possible to sort the DataGridView this way using a custom SortCompare method? If so, how?

2

There are 2 best solutions below

0
On BEST ANSWER

So what I did instead was I created a class for folder items named FolderItem. I then created a list of these FolderItem objects and populated the DataGridView using the list. It actually made it really easy--I just had to use this snippet of code:

List<FolderItem> items = new List<FolderItem>();

private void dgvFiles_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
    if(e.ColumnIndex == 1) {
        items.OrderBy(i => i.type).ThenBy(i => i.oldName);

        items.Reverse(); // to account for ascending/descending order

        RefreshDataGridView();
    }
}

public void RefreshDataGridView() {
    dgvFiles.Rows.Clear();

    foreach(FolderItem item in items) {
        dgvFiles.Rows.Add(item.icon, item.oldName, item.newName, item.type, item.size, item.created, item.modified);
    }
}

(type was null for folders so it occurred above the other items.)

You could also probably find some way to bind the datagridview to the list, but I didn't do that.

0
On

I depends on how you've set the image inside the column but instead of using e.CellValue1 and e.CellValue2 as you have done for the size sorting, use GridName.Rows[e.RowIndex1] and GridName.Rows[e.RowIndex2] to access the underlying data instead.