Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 更新数据源时刷新DataGridView_C#_.net_Winforms_Datagridview - Fatal编程技术网

C# 更新数据源时刷新DataGridView

C# 更新数据源时刷新DataGridView,c#,.net,winforms,datagridview,C#,.net,Winforms,Datagridview,更新基础数据源时,刷新DataGridView的最佳方法是什么 我经常更新数据源,希望在发生时向用户显示结果 我得到了类似这样的东西(它可以工作),但是将DataGridView.DataSource设置为null似乎不是正确的方法 List<ItemState> itemStates = new List<ItemState>(); dataGridView1.DataSource = itemStates; for (int i = 0; i < 10; i+

更新基础数据源时,刷新
DataGridView
的最佳方法是什么

我经常更新数据源,希望在发生时向用户显示结果

我得到了类似这样的东西(它可以工作),但是将
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);
}
List itemStates=new List();
dataGridView1.DataSource=ItemState;
对于(int i=0;i<10;i++){
Add(新的ItemState{Id=i.ToString()});
dataGridView1.DataSource=null;
dataGridView1.DataSource=ItemState;
系统.线程.线程.睡眠(500);
}
试试这段代码

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);
}
List itemStates=new List();
对于(int i=0;i<10;i++)
{ 
Add(新的ItemState{Id=i.ToString()});
dataGridView1.DataSource=ItemState;
dataGridView1.DataBind();
系统.线程.线程.睡眠(500);
}

嗯,没有比这更好的了。正式来说,你应该使用

dataGridView1.DataSource = typeof(List); 
dataGridView1.DataSource = itemStates;

这仍然是一种“清除/重置源”的解决方案,但我还没有找到任何其他可靠的方法来刷新DGV数据源。

我自己也遇到过这个问题。我的建议是:如果您拥有数据源的所有权,请不要使用。使用一个。具有在添加或更改项时激发的事件,并且在激发这些事件时将自动更新自身

这是我的答案

只需要像这样再次填充datagrid:

this.XXXTableAdapter.Fill(this.DataSet.XXX);

如果使用automaticlly connect from dataGridView,则此代码将以以下形式自动创建_Load()

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;
Observablecollection ItemState=新的Observablecollection();
对于(int i=0;i<10;i++){
Add(新的ItemState{Id=i.ToString()});
}
dataGridView1.DataSource=ItemState;

您正在循环内部设置数据源,并在每次添加后休眠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);
}
for(inti=0;i<10;i++){
Add(新的ItemState{Id=i.ToString()});
dataGridView1.DataSource=null;
dataGridView1.DataSource=ItemState;
系统.线程.线程.睡眠(500);
}
按如下方式更改代码:这要快得多

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);
for(inti=0;i<10;i++){
Add(新的ItemState{Id=i.ToString()});
}
dataGridView1.DataSource=typeof(列表);
dataGridView1.DataSource=ItemState;
系统.线程.线程.睡眠(500);

在这种情况下,最干净、最高效、最友好的解决方案是使用
System.Windows.Forms.BindingSource
作为项目列表(数据源)和
DataGridView
之间的代理:

var itemStates = new List<ItemState>();
var bindingSource1 = new System.Windows.Forms.BindingSource { DataSource = itemStates };
dataGridView1.DataSource = bindingSource1;
通过这种方式,您可以将项目添加到列表中,并使用同一行代码通知
DataGridView
。每次更改列表时,无需重置
DataGridView
DataSource


还值得一提的是,您可以在Visual Studio的表单设计器中将
BindingSource
直接放到表单上,并将其作为数据源附加到
DataGridView
中,这样可以在上面的示例中为您节省一行代码,我正在手动执行此操作。

Alexander Abakumov的答案是正确的。它解决了我在更新基础数据和网格更新时遇到的所有绑定问题

它很容易实现和修改任何现有的源代码

grdDetails.DataSource = new System.Windows.Forms.BindingSource { DataSource = OrderDetails };

使用“typeof(List)”而不是null有什么意义?@gwlosa,如果您使用的是自动生成的列,并且将数据源设置为null,则会清除这些列。通过使用typeof(List),它应该在刷新期间保持列结构。我个人会使用AutoGenerateColumns=false;并在第一次刷新时创建列。这样,如果用户调整列的大小,它就不会在刷新时丢弃他们所做的更改。@Alan为什么不使用BindingSource,然后您就可以刷新干净整洁的列,而不是像以前那样重新绑定?@CodeBlend-如果您指的是BindingSource.ResetBindings(),它就不会为我刷新项。需要“清除”DataSource属性并再次设置以查看任何更改。最好提供一个BindingSource的工作示例;)仅将
dataGridView1.DataSource
设置为新数据有什么问题。即使
AutoGenerateColumns
为true,也会自动更新网格,而不删除列的结构。这是一个很好的建议。在此之后,您只需调用.Refresh(),datagridview即可刷新其显示的数据…可以使用以下命令逐行刷新:bindingList.ResetItem(bindingList.IndexOf(item))
.Refresh()
只是讨论控件重绘,与绑定无关,除非我大错特错!“强制控件使其客户端区域无效,并立即重新绘制自身和所有子控件。”
BindingList
with
BindingSource
和使用
ResetBindings
对我不起作用。DataBind()是用于数据绑定控件的ASP.Net方法。此回答应该收到正确的回答标志。我的选票在这里。@jsa:不幸的是,
grdDetails.DataSource = new System.Windows.Forms.BindingSource { DataSource = OrderDetails };