简体   繁体   中英

DataGridView Custom Sort in WinForm

My DataGridView control currently sorts using the Sort property of the bound data, but it isn't doing what I want it to do.

I have a column called Employee that is displayed as "Firstname Lastname".

When I sort by Employee , Amy Z_Lastname is listed before John A_Lastname, meaning I would prefer to sort by last names.

I could break the Employee string up into 3 parts, include those in the DataTable, and set the sort to "Lastname, Firstname", then hide the Lastname and Firstname columns.

I'd rather learn how to override the default IComparer (or whatever it uses) to provide instructions on how to sort the way I want (the answer I'd prefer).

Custom sorting in the DataGridView

The DataGridView knows nothing of this ranking, of course. The default sorting scenario (automatic sorting for a data-bound column) of invoking DataGridView.Sort() via a column header mouse click simply delegates to the IBindingList implementation of ApplySort() in the list you've bound to the grid. Normally, this list would be a DataView. Using my ObjectListView implementation, this would be a view of a list of arbitrary business objects. Either way, you end up comparing the properties of the items in the list using the IComparable implementation of the property type.

Details

The PropertyComparers property exposes a PropertyComparersCollection, which is a dictionary of property name keys and IComparer values. You can replace the IComparer for a property by using the PropertyComparersCollection.Add() method or the indexer (eg view.PropertyComparers["PropName"] = myComparer). To revert to the default IComparable sorting, use the PropertyComparersCollection.Remove() method or set the IComparer value to null via the indexer.

If an IComparer is added to the PropertyComparers collection, it will be used for all subsequent sorts until it is removed from the collection or it is replaced with another IComparer. If the ObjectListView is already sorted when an IComparer is added to or removed from PropertyComparers, the view will automatically be re-sorted.

If you want to change multiple property comparers after the view is sorted, you can use the ObjectListView BeginUpdate() and EndUpdate() methods to suppress the ListChanged and Sort events until all of the IComparers have been changed. This prevents multiple refreshes of the DataGridView. If the ObjectListView is not sorted at the time IComparers are added or removed, no automatic re-sorting is done.

Note that when sorting on multiple columns, a custom IComparer can be used with one sort property, and the default IComparable sort on another.

eg:

private void radioButtonSortProgram_CheckedChanged(object sender, EventArgs e)

{

    if (this.radioButtonSortProgramAlpha.Checked)

        this.view.PropertyComparers["Program"] = new CustomerProgramComparerAlpha();

    else if (this.radioButtonSortProgramRank.Checked)

        this.view.PropertyComparers["Program"] = new CustomerProgramComparerRank();

    else

        this.view.PropertyComparers.Remove("Program");

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM