PaN*_*1Me 18 c# sorting datagridview
我正在使用Windows窗体DataGridView来显示MyObject对象的通用列表.
首先,我将此集合包装到BindingSourceCollection中,然后:
dataGridView.DataSource = myBindingSource;
Run Code Online (Sandbox Code Playgroud)
我想要做的是允许用户通过单击表示MyObject中具体属性的列标题对列进行排序.
我读过一些文章,我应该在绑定之前进行排序.但是,如果我想实时对列进行排序,那么它就无法帮助我.
问题是,我到底需要做什么,所以我可以看到 DataGridView中的排序箭头,我可以对每一列进行排序?
小智 30
完整代码,用于对datagridview列进行排序,其数据源是通用List
//-----------------------------------------------------------------------------------------
//In the form - In constructor or form load, populate the grid.
//--------------------------------------------------------------------------------------------
List<student> students;
private void PopulateList()
{
student std1 = new student("sss", 15, "Female");
student std2 = new student("ddd", 12, "Male");
student std3 = new student("zzz", 16, "Male");
student std4 = new student("qqq", 14, "Female");
student std5 = new student("aaa", 11, "Male");
student std6 = new student("lll", 13, "Female");
students = new List<student>();
students.Add(std1);
students.Add(std2);
students.Add(std3);
students.Add(std4);
students.Add(std5);
students.Add(std6);
dataGridView1.DataSource = students;
}
//---------------------------------------------------------------------------------------------
//Comparer class to perform sorting based on column name and sort order
//---------------------------------------------------------------------------------------------
class StudentComparer : IComparer<Student>
{
string memberName = string.Empty; // specifies the member name to be sorted
SortOrder sortOrder = SortOrder.None; // Specifies the SortOrder.
/// <summary>
/// constructor to set the sort column and sort order.
/// </summary>
/// <param name="strMemberName"></param>
/// <param name="sortingOrder"></param>
public StudentComparer(string strMemberName, SortOrder sortingOrder)
{
memberName = strMemberName;
sortOrder = sortingOrder;
}
/// <summary>
/// Compares two Students based on member name and sort order
/// and return the result.
/// </summary>
/// <param name="Student1"></param>
/// <param name="Student2"></param>
/// <returns></returns>
public int Compare(Student Student1, Student Student2)
{
int returnValue = 1;
switch (memberName)
{
case "Name" :
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Name.CompareTo(Student2.Name);
}
else
{
returnValue = Student2.Name.CompareTo(Student1.Name);
}
break;
case "Sex":
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Sex.CompareTo(Student2.Sex);
}
else
{
returnValue = Student2.Sex.CompareTo(Student1.Sex);
}
break;
default:
if (sortOrder == SortOrder.Ascending)
{
returnValue = Student1.Name.CompareTo(Student2.Name);
}
else
{
returnValue = Student2.Name.CompareTo(Student1.StudentId);
}
break;
}
return returnValue;
}
}
//---------------------------------------------------------------------------------------------
// Performing sort on click on Column Header
//---------------------------------------------------------------------------------------------
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
//get the current column details
string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
SortOrder strSortOrder = getSortOrder(e.ColumnIndex);
students.Sort(new StudentComparer(strColumnName, strSortOrder));
dataGridView1.DataSource = null;
dataGridView1.DataSource = students;
customizeDataGridView();
dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
}
/// <summary>
/// Get the current sort order of the column and return it
/// set the new SortOrder to the columns.
/// </summary>
/// <param name="columnIndex"></param>
/// <returns>SortOrder of the current column</returns>
private SortOrder getSortOrder(int columnIndex)
{
if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
{
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
return SortOrder.Ascending;
}
else
{
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
return SortOrder.Descending;
}
}
Run Code Online (Sandbox Code Playgroud)
我发现很难相信网格不提供开箱即用的基本排序,不需要代码.毕竟,必须处理标题点击事件并调用DataGridView.Sort指示列(由点击的内容,由网格跟踪确定)和排序方向(由当前排序状态确定,由网格跟踪)是非常愚蠢的).
为什么没有简单的SortMode或AllowUserToSort属性默认情况下执行完全相同的操作?
我已将网格绑定到List,并且我已将列映射到的属性都是基本类型,如string,int,DateTime等.所有这些都是IC Comparable.那么为什么我还需要写一行代码呢?特别是考虑到文档的内容如下:
默认情况下,用户可以通过单击文本框列的标题对DataGridView控件中的数据进行排序.
这是Framework 3.0文档,我的目标是3.5,但"其他版本"都是指Visual Studio的版本,而不是Framework的版本.微软究竟发生了什么?!?
我的解决方案是这样的:
我自己使用 myBindingSource,在单独的线程中进行排序、分组等操作。然后我只需将结果绑定到 DataGridView。
myDataGridView.DataSource = bindingSource;
Run Code Online (Sandbox Code Playgroud)
为此,我设置了所有要排序的列'Programatically'(在设计器中)然后我通过设置手动添加箭头(升序/降序)
cell.SortGlyphDirection = ... ;
Run Code Online (Sandbox Code Playgroud)
在后面的代码中。