Click here to Skip to main content
15,887,421 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a Folder/File ListView populated

1st [..] (Up one folder, always first)
2nd [Directory 1]
3rd [Directory 2]
4th etc...
5th [File 1]
6th [File 2]
7th etc...

I would like to keep the folders always above the files at all time even if you sort the columns. It all works fine is I turn on groups but I would like to avoid that(or make them invisible but I couldn't find any solution for that). The folders should be sorted compared to other folders and files to files. Is there a way to do this without using alternative ListView control or grouping?

What I have tried:

public class ListViewColumnSorter : IComparer
    {
        private int ColumnToSort;
        private string ColumnNameToSort = "";
        private SortOrder OrderOfSort;
        private CaseInsensitiveComparer ObjectCompare;

        public ListViewColumnSorter()
        {
            ColumnToSort = 0;
            OrderOfSort = SortOrder.None;
            ObjectCompare = new CaseInsensitiveComparer();
        }

        public int Compare(object x, object y)
        {
            int compareResult;
            ListViewItem listviewX, listviewY;
            listviewX = (ListViewItem)x;
            listviewY = (ListViewItem)y;
            string path = listviewX.Tag.ToString();
            string path2 = listviewY.Tag.ToString();
            switch (ColumnName)
            {
                case "Name":
                        compareResult = String.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
                    if (Order == SortOrder.Descending)
                        compareResult *= -1;
                    return compareResult;

                case "Extension":
                    compareResult = String.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
                    if (Order == SortOrder.Descending)
                        // Invert the value returned by Compare.
                        compareResult *= -1;
                    return compareResult;

                case "Size":
                    if (System.IO.File.Exists(path) & System.IO.File.Exists(path2))
                    {
                        FileInfo fi = new FileInfo(path);
                        FileInfo fi2 = new FileInfo(path2);
                        compareResult = ObjectCompare.Compare(fi.Length, fi2.Length);
                    }
                    else
                    {
                        compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
                    }
                    break;

                case "Last accessed":
                    {
                        DateTime x1, y1;
                        if (!DateTime.TryParse(listviewX.SubItems[ColumnToSort].Text, out x1))
                            x1 = DateTime.MinValue;
                        if (!DateTime.TryParse(listviewY.SubItems[ColumnToSort].Text, out y1))
                            y1 = DateTime.MinValue;
                        compareResult = DateTime.Compare(x1, y1);
                        if (x1 != DateTime.MinValue && y1 != DateTime.MinValue)
                            goto done;
                        compareResult = String.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);

                        done:
                        if (Order == SortOrder.Descending)
                            compareResult *= -1;
                        return compareResult;
                    }

                default:
                    compareResult = ObjectCompare.Compare(listviewX.SubItems[ColumnToSort].Text, listviewY.SubItems[ColumnToSort].Text);
                    break;
            }

            if (OrderOfSort == SortOrder.Ascending)
            {
                return compareResult;
            }
            else if (OrderOfSort == SortOrder.Descending)
            {
                return (-compareResult);
            }
            else
            {
                return 0;
            }
        }

        public int SortColumn
        {
            set
            {
                ColumnToSort = value;
            }
            get
            {
                return ColumnToSort;
            }
        }

        public string ColumnName
        {
            set
            {
                ColumnNameToSort = value;
            }
            get
            {
                return ColumnNameToSort;
            }
        }

        public SortOrder Order
        {
            set
            {
                OrderOfSort = value;
            }
            get
            {
                return OrderOfSort;
            }
        }
    }
Posted
Updated 11-Aug-18 11:30am

1 solution

Add a column just for sorting; e.g. "0" folder; "1" file.

Then "Hide" the "sorting" column; or, use a "sequence number" if display is useful.
 
Share this answer
 
Comments
Nagy_I_86 11-Aug-18 19:50pm    
If I use 0/1 and sort descending then the files will be above the directories again or I'm wrong? Also 0/1 sort will not sort it alphabetically just separate files and folders
[no name] 11-Aug-18 20:23pm    
You can sort on more than one column.

Columns can be sorted ascending or descending; independently.

You can have "conditional" sorting.

Anything else that I'm missing?
Nagy_I_86 12-Aug-18 10:44am    
I think your approach will be the right way to go but I cant figure out how to implement it. It is working for the "Name" column but it doesn't work for the others like "Extension" with values like ".EXE",".TXT",etc or "Last accessed" with dates.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900