C#DataGridView排序,以泛型列表作为基础源
我正在使用一个Windows窗体DataGridView来显示C#DataGridView排序,以泛型列表作为基础源,c#,sorting,datagridview,C#,Sorting,Datagridview,我正在使用一个Windows窗体DataGridView来显示MyObject对象的通用列表 首先,我将此集合包装到BindingSource集合中,然后: dataGridView.DataSource = myBindingSource; 我想做的是允许用户通过单击表示MyObject中具体属性的列标题对列进行排序 我读过一些文章,我应该在装订前进行排序。但是,如果我想对列进行实时排序,这对我没有帮助,因为它已经绑定好了 问题是,我到底需要做什么,这样才能在DataGridView中看到排
MyObject
对象的通用列表
首先,我将此集合包装到BindingSource
集合中,然后:
dataGridView.DataSource = myBindingSource;
我想做的是允许用户通过单击表示MyObject中具体属性的列标题对列进行排序
我读过一些文章,我应该在装订前进行排序。但是,如果我想对列进行实时排序,这对我没有帮助,因为它已经绑定好了
问题是,我到底需要做什么,这样才能在DataGridView中看到排序箭头,并对每一列进行排序
通过阅读,我看到“此方法通过比较指定列中的值对DataGridView的内容进行排序。默认情况下,排序操作将使用Compare方法使用DataGridViewCell..::.Value属性比较列中的单元格对。”
致以最良好的祝愿,
我的解决方案是:
我自己使用myBindingSource,我在一个单独的线程中进行排序、分组……任何操作。
然后我将结果绑定到DataGridView
myDataGridView.DataSource = bindingSource;
为此,我设置了所有要排序的列“编程”
(在designer中)
然后我手动添加箭头(升序/降序)
通过设置
cell.SortGlyphDirection = ... ;
在代码隐藏中。完成对datagridview的列进行排序的代码,该列的数据源是一个通用列表
//-----------------------------------------------------------------------------------------
//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;
}
}
//-----------------------------------------------------------------------------------------
//在form-In构造函数或form load中,填充网格。
//--------------------------------------------------------------------------------------------
列出学生名单;
私有void PopulateList()
{
学生std1=新生(“sss”,15,“女性”);
学生std2=新生(“ddd”,12,“男性”);
学生std3=新生(“zzz”,16,“男性”);
学生std4=新生(“qqq”,14,“女性”);
学生std5=新生(“aaa”,11,“男性”);
学生std6=新生(“lll”,13,“女性”);
学生=新列表();
学生。添加(std1);
学生。添加(std2);
学生。添加(std3);
学生。添加(std4);
学生。添加(std5);
学生。添加(std6);
dataGridView1.DataSource=学生;
}
//---------------------------------------------------------------------------------------------
//比较器类根据列名和排序顺序执行排序
//---------------------------------------------------------------------------------------------
班级学生比较者:I比较者
{
string memberName=string.Empty;//指定要排序的成员名称
SortOrder SortOrder=SortOrder.None;//指定排序器。
///
///构造函数来设置排序列和排序顺序。
///
///
///
public StudentComparier(字符串strMemberName、排序器排序顺序)
{
memberName=strMemberName;
sortOrder=排序顺序;
}
///
///根据成员名称和排序顺序比较两个学生
///并返回结果。
///
///
///
///
公共整数比较(学生1、学生2)
{
int返回值=1;
开关(成员名称)
{
案例“名称”:
if(sortOrder==sortOrder.升序)
{
returnValue=Student1.Name.CompareTo(Student2.Name);
}
其他的
{
returnValue=Student2.Name.CompareTo(Student1.Name);
}
打破
“性别”一案:
if(sortOrder==sortOrder.升序)
{
returnValue=Student1.Sex.CompareTo(Student2.Sex);
}
其他的
{
returnValue=Student2.Sex.CompareTo(Student1.Sex);
}
打破
违约:
if(sortOrder==sortOrder.升序)
{
returnValue=Student1.Name.CompareTo(Student2.Name);
}
其他的
{
returnValue=Student2.Name.CompareTo(Student1.StudentId);
}
打破
}
返回值;
}
}
//---------------------------------------------------------------------------------------------
//单击列标题执行排序
//---------------------------------------------------------------------------------------------
私有void dataGridView1_ColumnHeaderMouseClick(对象发送者,DataGridViewCellMouseEventArgs e)
{
//获取当前列的详细信息
字符串strColumnName=dataGridView1.Columns[e.ColumnIndex].Name;
SortOrder strSortOrder=getSortOrder(如ColumnIndex);
排序(newstudentcomparer(strColumnName,strSortOrder));
dataGridView1.DataSource=null;
dataGridView1.DataSource=学生;
自定义TagRidView();
dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection=strSortOrder;
}
///
///获取列的当前排序顺序并返回它
///将新排序器设置为列。
///
///
///当前列的排序器
私有排序器getSortOrder(int-columnIndex)
{
如果(dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection==SortOrder.None||
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection==SortOrder.Descending)
{
dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection=SortOrder.Ascending;
返回排序器。上升;
}
其他的
{
dataGridView1
private List<CompareInfo> compareList;
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
SortOrder strSortOrder = getSortOrder(e.ColumnIndex);
if (strSortOrder == SortOrder.Ascending)
{
compareList = compareList.OrderBy(x => typeof(CompareInfo).GetProperty(strColumnName).GetValue(x, null)).ToList();
}
else
{
compareList = compareList.OrderByDescending(x => typeof(CompareInfo).GetProperty(strColumnName).GetValue(x, null)).ToList();
}
dataGridView1.DataSource = compareList;
dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
}
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;
}
}
public class CompareInfo
{
public string FileName { get; set; }
public string UAT_Folder { get; set; }
public string UAT_Path
{
get { return UAT_Folder + FileName; }
}
public string PROD_Folder { get; set; }
public string PROD_Path
{
get { return PROD_Folder + FileName; }
}
}
private string _lastSortColumn;
private ListSortDirection _lastSortDirection;
public void Sort(DataGridViewColumn column)
{
// Flip sort direction, if the column chosen was the same as last time
if (column.Name == _lastSortColumn)
_lastSortDirection = 1 - _lastSortDirection;
// Otherwise, reset the sort direction to its default, ascending
else
{
_lastSortColumn = column.Name;
_lastSortDirection = ListSortDirection.Ascending;
}
// Prep data for sorting
var data = (IEnumerable<dynamic>)DataSource;
var orderProperty = column.DataPropertyName;
// Sort data
if (_lastSortDirection == ListSortDirection.Ascending)
DataSource = data.OrderBy(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();
else
DataSource = data.OrderByDescending(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();
// Set direction of the glyph
Columns[column.Index].HeaderCell.SortGlyphDirection
= _lastSortDirection == ListSortDirection.Ascending
? SortOrder.Ascending : SortOrder.Descending;
}
protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
{
base.OnColumnHeaderMouseClick(e);
var column = Columns[e.ColumnIndex];
if (column.SortMode == DataGridViewColumnSortMode.Automatic
|| column.SortMode == DataGridViewColumnSortMode.NotSortable)
Sort(column);
}
public DataTable ToDataTable<T>(List<T> items)
{
DataTable dataTable = new DataTable(typeof(T).Name);
//Get all the properties
PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public |
BindingFlags.Instance);
foreach (PropertyInfo prop in Props)
{
//Setting column names as Property names
dataTable.Columns.Add(prop.Name);
}
foreach (T item in items)
{
var values = new object[Props.Length];
for (int i = 0; i < Props.Length; i++)
{
//inserting property values to datatable rows
values[i] = Props[i].GetValue(item, null);
}
dataTable.Rows.Add(values);
}
//put a breakpoint here and check datatable
return dataTable;
}