C# 更新数据源时刷新 DataGridView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/253843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Refresh DataGridView when updating data source
提问by shaunf
What is the best way to refresh a DataGridView
when you update an underlying data source?
DataGridView
更新基础数据源时刷新 a 的最佳方法是什么?
I'm updating the datasource frequently and wanted to display the outcome to the user as it happens.
我经常更新数据源,并希望在发生时向用户显示结果。
I've got something like this (and it works), but setting the DataGridView.DataSource
to null
doesn't seem like the right way.
我有这样的东西(并且它有效),但是将 设置DataGridView.DataSource
为null
似乎不是正确的方法。
List<ItemState> itemStates = new List<ItemState>();
dataGridView1.DataSource = itemStates;
for (int i = 0; i < 10; i++) {
itemStates.Add(new ItemState { Id = i.ToString() });
dataGridView1.DataSource = null;
dataGridView1.DataSource = itemStates;
System.Threading.Thread.Sleep(500);
}
采纳答案by Alan
Well, it doesn't get much better than that. Officially, you should use
嗯,没有比这更好的了。正式地,你应该使用
dataGridView1.DataSource = typeof(List);
dataGridView1.DataSource = itemStates;
It's still a "clear/reset source" kind of solution, but I have yet to find anything else that would reliably refresh the DGV data source.
它仍然是一种“清除/重置源”类型的解决方案,但我还没有找到任何其他可以可靠地刷新 DGV 数据源的方法。
回答by Georg
Try this Code
试试这个代码
List itemStates = new List();
for (int i = 0; i < 10; i++)
{
itemStates.Add(new ItemState { Id = i.ToString() });
dataGridView1.DataSource = itemStates;
dataGridView1.DataBind();
System.Threading.Thread.Sleep(500);
}
回答by GWLlosa
I ran into this myself. My recommendation: If you have ownership of the datasource, don't use a List. Use a BindingList. The BindingListhas events that fire when items are added or changed, and the DataGridViewwill automatically update itself when these events are fired.
我自己遇到了这个。我的建议:如果您拥有数据源的所有权,请不要使用List。使用BindingList。该的BindingList有事件,当项目被添加或更改,而火的DataGridView当这些事件被触发将自动更新。
回答by starko
回答by Kashif
Observablecollection:Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. You can enumerate over any collection that implements the IEnumerable interface. However, to set up dynamic bindings so that insertions or deletions in the collection update the UI automatically, the collection must implement the INotifyCollectionChanged interface. This interface exposes the CollectionChanged event, an event that should be raised whenever the underlying collection changes.
Observablecollection:表示动态数据集合,在添加、删除项目或刷新整个列表时提供通知。您可以枚举实现 IEnumerable 接口的任何集合。但是,要设置动态绑定以使集合中的插入或删除自动更新 UI,该集合必须实现 INotifyCollectionChanged 接口。此接口公开 CollectionChanged 事件,该事件应在基础集合更改时引发。
Observablecollection<ItemState> itemStates = new Observablecollection<ItemState>();
for (int i = 0; i < 10; i++) {
itemStates.Add(new ItemState { Id = i.ToString() });
}
dataGridView1.DataSource = itemStates;
回答by Stix
You are setting the datasource inside of the loop and sleeping 500 after each add. Why not just add to itemstates and then set your datasource AFTER you have added everything. If you want the thread sleep after that fine. The first block of code here is yours the second block I modified.
您在循环内设置数据源并在每次添加后睡眠 500。为什么不直接添加到 itemstates,然后在添加所有内容后设置数据源。如果你想让线程在那之后休眠。这里的第一个代码块是我修改的第二个代码块。
for (int i = 0; i < 10; i++) {
itemStates.Add(new ItemState { Id = i.ToString() });
dataGridView1.DataSource = null;
dataGridView1.DataSource = itemStates;
System.Threading.Thread.Sleep(500);
}
Change your Code As follows:this is much faster.
如下更改您的代码:这要快得多。
for (int i = 0; i < 10; i++) {
itemStates.Add(new ItemState { Id = i.ToString() });
}
dataGridView1.DataSource = typeof(List);
dataGridView1.DataSource = itemStates;
System.Threading.Thread.Sleep(500);
回答by Alexander Abakumov
The cleanest, most efficient and paradigm-friendly solution in this case is to use a System.Windows.Forms.BindingSource
as a proxy between your list of items (datasource) and your DataGridView
:
在这种情况下,最干净、最有效和范式友好的解决方案是使用 aSystem.Windows.Forms.BindingSource
作为您的项目列表(数据源)和您的 之间的代理DataGridView
:
var itemStates = new List<ItemState>();
var bindingSource1 = new System.Windows.Forms.BindingSource { DataSource = itemStates };
dataGridView1.DataSource = bindingSource1;
Then, when adding items, use Add()
method of BindingSource
instead of your list's Add()
method:
然后,在添加项目时,使用Add()
方法BindingSource
而不是列表的Add()
方法:
for (var i = 0; i < 10; i++)
{
bindingSource1.Add(new ItemState { Id = i.ToString() });
System.Threading.Thread.Sleep(500);
}
This way you adding items to your list and notifying DataGridView
about those additions with the same line of code. No need to reset DataGridView
's DataSource
every time you make a change to the list.
通过这种方式,您可以将项目添加到列表中,并DataGridView
使用同一行代码通知这些添加内容。每次对列表进行更改时都无需重置DataGridView
's DataSource
。
It also worth mentioning that you can drop a BindingSource
onto your form directly in Visual Studio's Forms Designer and attach it as a data source to your DataGridView
there as well, which saves you a line of code in the above example where I'm doing it manually.
还值得一提的是,您可以BindingSource
直接在 Visual Studio 的表单设计器中将 a拖放到您的表单上,并将其作为数据源附加到您的表单中,这为您DataGridView
节省了上面示例中我手动执行的一行代码。
回答by Kim
Alexander Abakumov's answer is the correct one. It solved every binding issue I had updating the underlying data and having the grid update.
亚历山大·阿巴库莫夫的回答是正确的。它解决了我更新基础数据和更新网格时遇到的每个绑定问题。
Its easy to implement and modify any existing source code you have.
它易于实现和修改您拥有的任何现有源代码。
grdDetails.DataSource = new System.Windows.Forms.BindingSource { DataSource = OrderDetails };