使用 BindingSource 对 DataGridView 进行自定义排序
Custom Sort on DataGridView with BindingSource
我试图提高在我的 DataGridView 中加载相对大量数据的性能,我发现从设置 DGV 的数据源到它完全呈现之间的时间非常长。我将其隔离到我的 DataBindingComplete 事件中列格式的动态设置,该事件(在逐步查找之后)不是在每列的基础上应用格式,而是以某种方式在每个单元格的基础上进行(!!)。当单元格数量很大时,这显然会阻塞渲染。
我开始修改内存中的数据,通过 value.ToString("N")
将 DataTable 值从双精度更改为格式化字符串。这显着加快了渲染速度,但我留下了几列字符串而不是双打,这破坏了网格的自然排序能力。我搜索了很多,是否可以在 DataGridView 级别、BindingSource 级别或 DataTable 级别上进行自定义排序,但无济于事。
如果有人能给我指出正确的方向,我将不胜感激,尤其是如果这种方法完全不是一个好主意,并且有更好的方法来完成数字格式化等简单任务。
我想 this article 是您要找的?您可以通过实现 IComparer<T>
接口并使用您的自定义 Compare
方法,使用 LINQ 对 BindingSource 进行自定义排序(我想您无论如何都在使用 LINQ?)。
对于列格式,如果需要格式化,可以这样做,示例是日期时间值:
dataGridView1.Columns["Column"].DefaultCellStyle.Format = "MM-dd-yyyy";
对于自定义排序,如果您从 sql 服务器获取数据,您可以让它在查询中对它 returns 的行进行排序,它会在 dataGridView 中按该顺序显示它们,这是我为此目的使用的代码:
string command = "SELECT * FROM [table] ORDER BY [column]";
//database connection string
string constring =[database connection string];
//open DB connection - execute query - create dataadapter - fill datatable - bind datasource to datatable
using (SqlConnection con = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand(command, con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
try
{
//fill the dataGridView
sda.Fill(dt);
dataGridView1.DataSource = dt;
Console.WriteLine("Refreshing Complete");
//disable manual sorting on all columns
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
}
//Autosize all cells
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoResizeColumns();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
}
这会按照返回行的顺序将查询输出绑定到 dataGridView,将行的手动排序设置为 false 并自动调整所有列的大小。
如果你想重新填充 dataGridView 你可以使用这个:
dataGridView1.DataSource = null;
dataGridView1.Refresh();
然后运行再次填充。
如果需要,您还可以在查询输出绑定期间更改列的显示顺序和列 header 名称。
我希望这有点帮助
我试图提高在我的 DataGridView 中加载相对大量数据的性能,我发现从设置 DGV 的数据源到它完全呈现之间的时间非常长。我将其隔离到我的 DataBindingComplete 事件中列格式的动态设置,该事件(在逐步查找之后)不是在每列的基础上应用格式,而是以某种方式在每个单元格的基础上进行(!!)。当单元格数量很大时,这显然会阻塞渲染。
我开始修改内存中的数据,通过 value.ToString("N")
将 DataTable 值从双精度更改为格式化字符串。这显着加快了渲染速度,但我留下了几列字符串而不是双打,这破坏了网格的自然排序能力。我搜索了很多,是否可以在 DataGridView 级别、BindingSource 级别或 DataTable 级别上进行自定义排序,但无济于事。
如果有人能给我指出正确的方向,我将不胜感激,尤其是如果这种方法完全不是一个好主意,并且有更好的方法来完成数字格式化等简单任务。
我想 this article 是您要找的?您可以通过实现 IComparer<T>
接口并使用您的自定义 Compare
方法,使用 LINQ 对 BindingSource 进行自定义排序(我想您无论如何都在使用 LINQ?)。
对于列格式,如果需要格式化,可以这样做,示例是日期时间值:
dataGridView1.Columns["Column"].DefaultCellStyle.Format = "MM-dd-yyyy";
对于自定义排序,如果您从 sql 服务器获取数据,您可以让它在查询中对它 returns 的行进行排序,它会在 dataGridView 中按该顺序显示它们,这是我为此目的使用的代码:
string command = "SELECT * FROM [table] ORDER BY [column]";
//database connection string
string constring =[database connection string];
//open DB connection - execute query - create dataadapter - fill datatable - bind datasource to datatable
using (SqlConnection con = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand(command, con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
try
{
//fill the dataGridView
sda.Fill(dt);
dataGridView1.DataSource = dt;
Console.WriteLine("Refreshing Complete");
//disable manual sorting on all columns
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
}
//Autosize all cells
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView1.AutoResizeColumns();
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
}
}
}
这会按照返回行的顺序将查询输出绑定到 dataGridView,将行的手动排序设置为 false 并自动调整所有列的大小。 如果你想重新填充 dataGridView 你可以使用这个:
dataGridView1.DataSource = null;
dataGridView1.Refresh();
然后运行再次填充。 如果需要,您还可以在查询输出绑定期间更改列的显示顺序和列 header 名称。 我希望这有点帮助