|
Hello to All. I'm trying to implement a multi sort option in dataGridView. I can do it by creating a new SelectCommand and rebind it to the control, by this approach have 2 disadvantages:
1. On big database, rebind data is a heavy command, and to rebind data seem to be a waste, when I have all the data already in my DataGridView.
2. Trying to create a multi-sort dataGridView with this approach, while the select command is unknown (could be simple select * from customers or complicated-combined select, with and without Order By clause in it) won't work perfectly to all select command I.e.: adding the command "Order By [Field1], [Field2]" could resolved in an error when Order By already exists in the SelectCommand.
Please, anything that might help will be appreciated.
Eli
| | MigrationUser 1 Friday, March 25, 2005 2:22 AM | It's ok. I've manage to implement the multi-sort, using the System.Collections.IComparer interface, to send to DataGridView.Sort() method.
It takes 2 rows from the current datagridview, and compare each column by the selected order. it works fine.
Thanks anyway. | | MigrationUser 1 Saturday, March 26, 2005 5:57 AM | That is the correct way to go! Do you mind sharing your code for your IComparer for others to learn from?
thanks! -mark .NET Client Program Manager Microsoft This post is provided "as-is"
| | MigrationUser 1 Tuesday, March 29, 2005 2:25 PM | This is the multi sort class:
public class MultiSortComparer : System.Collections.IComparer { private string[] columnNames; private SortOrder[] columnOrder;
public MultiSortComparer(string[] columnNames, SortOrder[] columnOrder) { this.columnNames = columnNames; this.columnOrder = columnOrder; }
public int Compare(object x, object y) { DataGridViewRow row1 = (DataGridViewRow)x; DataGridViewRow row2 = (DataGridViewRow)y;
// the comapre result to send in the end of the method int compareResult = 0; string compareColumn = ""; // the column index to compare by at wach iteration int columnIndex = 0; // sort will continue until compare_result != 0 bool isSortNedded = true; while (isSortNedded) { compareColumn = columnNames[columnIndex]; compareResult = Compare_Object(row1.Cells[compareColumn].Value, row2.Cells[compareColumn].Value); // continue to next cell index ++columnIndex; // if cells are equal --> continue comapre at next cell // also, end of loop when there are no more column to check isSortNedded = (compareResult == 0) && (columnIndex < columnNames.Length); } // the result is multiply by up and down settings // dec index by one because its added before for next iteration int sortOrderValue = 0; if (columnOrder == null || columnOrder.Length <= columnIndex - 1 || columnOrder[columnIndex - 1] == SortOrder.None) { sortOrderValue = 0; } else { sortOrderValue = (columnOrder[columnIndex - 1] == SortOrder.Ascending ? 1 : -1); } return compareResult * sortOrderValue; }
private int Compare_Object(object o1, object o2) { // object are null - equal if (o1 == null && o2 == null) return 0; // o1 is null o2 is not - o2 is bigger if (o1 == null && o2 != null) return -1; // o2 is null o1 is not - o1 is bigger if (o1 != null && o2 == null) return 1; // o1 and o2 is not the same type - equal if (o1.GetType() != o2.GetType()) return 0; // int or double or float or long if (o1 is string) { string s1 = o1.ToString(); string s2 = o2.ToString(); return s1.CompareTo(s2); } if (o1 is DateTime) { DateTime d1 = (DateTime)o1; DateTime d2 = (DateTime)o2; return d1.CompareTo(d2); }
if (o1 is int) { int n1 = (int)o1; int n2 = (int)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is bool) { bool b1 = (bool)o1; bool b2 = (bool)o2; return (b1 == b2 ? 0: b1==true ? 1 : -1); }
if (o1 is float) { float n1 = (float)o1; float n2 = (float)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is double) { double n1 = (double)o1; double n2 = (double)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is long) { long n1 = (long)o1; long n2 = (long)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } return 0; } }
To use this in the DataGridView object call this method in the DataGridView:
public bool MultiSort(string[] columnNamesToSort, SortOrder[] sortOrder) { if (columnNamesToSort != null && columnNamesToSort.Length > 0) { this.Sort(new MultiSortComparer( columnNamesToSort, sortOrder )); return true; } return false; }
Hope it helps.
Eli | | MigrationUser 1 Monday, May 09, 2005 7:24 AM | To allow multi sort on a DataGridView call this method (this is a DataGridView extended object) :
/// <summary> /// Multi sort the grid. /// The sort order will be from 0 item on the columnNamesToSort array until /// the N-1 item. Sort order is used to determine ascending/descending or none /// options. if no sort order items are set, default is acsending. /// </summary> /// <param name="columnNamesToSort">column names to sort, starting from item 0</param> /// <param name="sortOrder">sorting order array matching the columns name array</param> /// <returns></returns> public bool MultiSort(string[] columnNamesToSort, SortOrder[] sortOrder) { if (columnNamesToSort != null && columnNamesToSort.Length > 0) { this.Sort(new MultiSortComparer( columnNamesToSort, sortOrder )); return true; } return false; }
This is the multiSort class that I use to allow the multi sort:
public class MultiSortComparer : System.Collections.IComparer { private string[] columnNames; private SortOrder[] columnOrder;
public MultiSortComparer(string[] columnNames, SortOrder[] columnOrder) { this.columnNames = columnNames; this.columnOrder = columnOrder; }
public int Compare(object x, object y) { DataGridViewRow row1 = (DataGridViewRow)x; DataGridViewRow row2 = (DataGridViewRow)y;
// the comapre result to send in the end of the method int compareResult = 0; string compareColumn = ""; // the column index to compare by at wach iteration int columnIndex = 0; // sort will continue until compare_result != 0 bool isSortNedded = true; while (isSortNedded) { compareColumn = columnNames[columnIndex]; compareResult = Compare_Object(row1.Cells[compareColumn].Value, row2.Cells[compareColumn].Value);
// continue to next cell index ++columnIndex; // if cells are equal --> continue comapre at next cell // also, end of loop when there are no more column to check isSortNedded = (compareResult == 0) && (columnIndex < columnNames.Length); } // the result is multiply by up and down settings // dec index by one because its added before for next iteration int sortOrderValue = 0; if (columnOrder == null || columnOrder.Length <= columnIndex - 1 || columnOrder[columnIndex - 1] == SortOrder.None) { sortOrderValue = 0; } else { sortOrderValue = (columnOrder[columnIndex - 1] == SortOrder.Ascending ? 1 : -1); } return compareResult * sortOrderValue; }
private int Compare_Object(object o1, object o2) { // object are null - equal if (o1 == null && o2 == null) return 0; // o1 is null o2 is not - o2 is bigger if (o1 == null && o2 != null) return -1; // o2 is null o1 is not - o1 is bigger if (o1 != null && o2 == null) return 1; // o1 and o2 is not the same type - equal if (o1.GetType() != o2.GetType()) return 0; // int or double or float or long if (o1 is string) { string s1 = o1.ToString(); string s2 = o2.ToString(); return s1.CompareTo(s2); } if (o1 is DateTime) { DateTime d1 = (DateTime)o1; DateTime d2 = (DateTime)o2; return d1.CompareTo(d2); }
if (o1 is int) { int n1 = (int)o1; int n2 = (int)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is bool) { bool b1 = (bool)o1; bool b2 = (bool)o2; return (b1 == b2 ? 0: b1==true ? 1 : -1); }
if (o1 is float) { float n1 = (float)o1; float n2 = (float)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is double) { double n1 = (double)o1; double n2 = (double)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); } if (o1 is long) { long n1 = (long)o1; long n2 = (long)o2; return (n1 > n2 ? 1 : n1 < n2 ? -1 : 0); }
return 0;
} }
Hope it helps.
Eli
| | MigrationUser 1 Monday, May 09, 2005 7:44 AM | Very cool. Thanks for sharing with everyone!
-mark Program Manager Microsoft This post is provided "as-is" | | MigrationUser 1 Monday, May 09, 2005 4:01 PM | Or do it the lazy man's way at the binding source:
BindingSource1.Sort = "Country DESC, Address ASC";
Bryan
| | theBainster Thursday, September 22, 2005 8:51 PM |
|