BLOG.CSHARPHELPER.COM: Add useful extension methods to the ListView control to let it sort using all columns or clicked columns in C#
Add useful extension methods to the ListView control to let it sort using all columns or clicked columns in C#
This example is somewhat involved so I'm going to mostly explain how the pieces fit together and let you look at the code and at other examples to see how each piece works. This example uses techniques described in the following examples:
This example adds the following useful extension methods to the ListView class:
AddRow
Adds a new item and subitems to define a row in the ListView.
SetColumnHeaders
Defines column headers and their alignments.
SetColumnSizes
Sets all columns to the same size.
SizeColumnsToFitData
Sizes all columns to fit their data.
SizeColumnsToFitDataAndHeaders
Sizes all columns to fit their data and headers.
SetSortMode
Sets the control's sort mode to SortNone, SortOnClickedColumn, or SortOnAllColumns.
All but the last of these are relatively simple extension methods that use the techniques explained by the example Easily add column headers and items to a ListView control in C#.
The SetSortMode method lets you determine whether the ListView doesn't sort its items, sorts by the columns you click, or sorts on all columns. (For example, suppose two rows have identical values in the first three columns but differ in the fourth. Sorting on all columns lets the control property order the rows.) The following code shows the SetSortMode extension method.
// Prepare the ListView for column sorting.
public enum SortMode
{
SortNone,
SortOnClickedColumn,
SortOnAllColumns
}
public static void SetSortMode(this ListView lvw, SortMode sort_mode)
{
// Get the current sort mode.
SortMode old_sort_mode =
(SortMode)lvw.GetValue("ListViewSortMode", SortMode.SortNone);
// If the sort mode isn't changing, do nothing.
if (sort_mode == old_sort_mode) return;
// See what the current sorting mode is.
if (old_sort_mode == SortMode.SortOnClickedColumn)
{
// Stop sorting on clicked columns.
ListViewSortManager SortManager =
(ListViewSortManager)lvw.GetValue("ListViewSortManager", null);
SortManager.Disable();
lvw.RemoveValue("ListViewSortManager");
lvw.ListViewItemSorter = null;
}
else if (old_sort_mode == SortMode.SortOnAllColumns)
{
// Stop sorting on all columns.
lvw.ListViewItemSorter = null;
}
// Start the new sort mode.
if (sort_mode == SortMode.SortNone)
{
lvw.RemoveValue("ListViewSortMode");
return;
}
if (sort_mode == SortMode.SortOnClickedColumn)
{
// Sort on clicked columns.
lvw.SetValue("ListViewSortManager", new ListViewSortManager(lvw));
}
else if (sort_mode == SortMode.SortOnAllColumns)
{
// Sort on all columns.
lvw.ListViewItemSorter = new ListViewAllColumnComparer(SortOrder.Ascending);
lvw.Sort();
}
// Save the new sort mode.
lvw.SetValue("ListViewSortMode", sort_mode);
}
This code starts by defining the SortMode enumeration. The method itself uses an extension property named ListViewSortMode to hold the control's SortMode value. It starts by getting the current value of that property. If the current SortMode value is the same as the new one, the method simply returns.
Next the method removes the objects that provide the current sorting method. If the current method is SortOnClickedColumn, the code gets the extension property ListViewSortManager. That value is an object used to implement the SortOnClickedColumn strategy. It provides an event handler that catches the ListView control's ColumnClicked event and creates an appropriate object to sort the ListView's data. See the code and the example Make a ListView sort using the column you click in C# for details about how that kind of sorting works.
If the current sort method is SortOnAllColumns, the code sets the ListView's ListViewItemSorter property to null. That object is of a class that implements the IComparer interface and that provides a Compare method for the ListView that sorts its rows by using all columns. (The ListViewSortManager also sets the ListView's ListViewItemSorter property behind the scenes.) For more on using the ListViewItemSorter property, see the example
Make a ListView control sort using all of its columns in C#.
(If the current sort mode is SortNone, the program doesn't need to remove the current sorting method.)
Having removed the current sort mode, the method adds the new one. If the new sort mode is SortNone, the code removes the ListView's ListViewSortMode extension property and returns.
If the new sort mode is SortOnClickedColumn, the method creates a new ListViewSortManager and saves it in the control's ListViewSortManager extension property. The manager's constructor initializes the object so it is ready to sort by clicked columns. In particular it installs an event handler to catch the ListView's ColumnClicked event so it can sort on the clicked column.
If the new sort mode is SortOnClickedColumn, the method creates a new ListViewAllColumnComparer, assigns it to the ListView's ListViewItemSorter property, and calls the ListView's Sort method to make it sort its data.
Finally the method saves the new sort mode in the ListView's ListViewSortMode extension property so it will know the sorting mode the next time the SetSortMode method is called.
The following code shows how the main program uses SetSortMode when you click on one of its radio buttons.
// Sort on clicked columns.
private void radSortClickedColumn_Click(object sender, EventArgs e)
{
lvwBooks.SetSortMode(ListViewExtensions.SortMode.SortOnClickedColumn);
}
// Sort on all columns.
private void radSortAllColumns_Click(object sender, EventArgs e)
{
lvwBooks.SetSortMode(ListViewExtensions.SortMode.SortOnAllColumns);
}
// Do not sort.
private void radNoSort_Click(object sender, EventArgs e)
{
lvwBooks.SetSortMode(ListViewExtensions.SortMode.SortNone);
}
This code simply calls the ListView's SetSortMode extension method passing it the desired sort mode. The rest is automatic.
Comments