如何在更新后刷新C# dataGridView?

38
我有一个 dataGridView,当我点击任何一行时,会打开一个表单来更新行数据,但更新完成后,更新表单关闭了,但是 dataGridView 中的数据没有更新。
如何解决这个问题?

dataGridView1.Refresh(); - Gilad Naaman
3
Refresh(); 是图形刷新,而不是数据刷新。我也犯了同样的错误!简介:强制控件无效化其客户区域并立即重绘自身和任何子控件。 - Paul C
5
@amer:你应该接受一些回答来回答你的问题。 - Ian
10个回答

55

BindingSource 是一种不使用第三方ORM的方式,虽然一开始可能会感觉有些冗长,但在BindingSource上拥有一个更新方法所带来的好处是非常有帮助的。

如果你的数据源是例如用户字符串列表的话

List<string> users = GetUsers();
BindingSource source = new BindingSource();
source.DataSource = users;
dataGridView1.DataSource = source;

完成编辑后,只需更新数据对象,无论是DataTable还是像这样的用户字符串列表,并在BindingSource上进行ResetBindings操作。

users = GetUsers(); //Update your data object
source.ResetBindings(false);

嗯,从“简单的DataGridView刷新问题”过来,这个ResetBinding()调用在我的简单测试项目中仍然不起作用;)你能给出一个实际的、可构建的、正常刷新的示例吗? - Alan
5
ResetBindings 似乎只适用于 .net 类型。如果您使用自定义集合,我认为您需要实现 IBindingList 接口,但我还没有尝试过。 - Ed Sykes
什么是自定义集合? - Paul C
尚未尝试过 @EdSykes 的建议使用 IBindingList,但不幸的是,它也不能与 BindingList<T> 一起使用。 - Toby
我以为把所有的数据表格都转换会很麻烦,但是实际上并不是。谢谢 :) - TomeeNS

40
重新绑定你的DataGridView与数据源。
DataGridView dg1 = new DataGridView();
dg1.DataSource = src1;

// Update Data in src1

dg1.DataSource = null;
dg1.DataSource = src1;

这只是一个例子,你只需要底部的两行,并且希望它们在更新后出现。因此,在父项上,在子项关闭事件中想象一下。 - Ian
这是我以前的做法,它确实可以正常工作,但我发现使用一个带有'ResetBindings'方法的'BindingSource'(如我的答案所述)非常棒! - Paul C
1
@Ian:也许值得更新你的示例并提到,如果将DataSource属性设置为null,则会丢失模式(列)。通常最好将其设置为typeof(ElementType),其中ElementType是绑定行的类型。 - Alan
虽然它可以工作,但您需要重置一些DataGridView的属性,例如列标题文本、列大小和某些列的可见性,例如ID等。 - Vahid Ghadiri

7

我知道这是一个老话题,但我突然找到了最好的方法,并且不需要使数据源失效并重新分配它。只需使用BindingList而不是List即可。

例如:

//declare your list
private BindingList<myclass> mMyList = new BindingList<myclass>();

//then bind it to your datagrid, i usually do it on the Load event
private void Form1_Load(object sender, EventArgs e)
{
    _dgMyDatagrig.DataSource = mMyList;
}

//start populating your list 
private void addItem(mycclass item)
{
    mMylist.add(item);

//the datagrid will show automatically the new added/updated items, no need to do anything else

}

这样做可以避免每次添加新项目时页面滚动到顶部。 - Nguyen Viet Cuong
这可以工作,但由于跨线程GUI更新,您需要调用Add()操作。 - Pedro Ferreira
太棒了,我之前一直在使用上面回答中的Binding Source - 但是使用BindingList时自动滚动回到顶部的功能对我的应用程序来说是一个很大的优势。谢谢! - jwilo

4

我知道我来晚了,但希望这能帮助那些使用类绑定的人

var newEntry = new MyClassObject();

var bindingSource = dataGridView.DataSource as BindingSource;
var myClassObjects = bindingSource.DataSource as List<MyClassObject>;
myClassObjects.Add(newEntry);
bindingSource.DataSource = myClassObjects;

dataGridView.DataSource = null;
dataGridView.DataSource = bindingSource;
dataGridView.Update();
dataGridView.Refresh();

2

我使用DataGridView的Invalidate()函数。然而,这会刷新整个DataGridView。如果您想刷新特定行,则使用dgv.InvalidateRow(rowIndex)。如果您想刷新特定单元格,则可以使用dgv.InvalidateCell(columnIndex, rowIndex)。当然,前提是您使用绑定源或数据源。


1
你可以使用DataGridView的刷新方法。但是,在许多情况下,您必须从运行在与DataGridView不同线程上的方法中刷新DataGridView。为了做到这一点,您应该实现以下方法并调用它,而不是直接键入DataGridView.Refresh():
    private void RefreshGridView()
    {
        if (dataGridView1.InvokeRequired)
        {
            dataGridView1.Invoke((MethodInvoker)delegate ()
            {
                RefreshGridView();
            });
        }
        else
            dataGridView1.Refresh();
    }  

0
我发现了这个有用的.NET文档,它展示了如何正确地重置绑定,使用BindingSource.ResetBindings

0
我不确定这个问题是否已经解决了...但是看了所有其他答案,似乎没有一个很清晰的。我发现最好的方法是将用于填充你的datagridview的相同代码放入一个方法中,并将其传递给你的表单的datagridview,如下所示:
public void ConnectAndPopulateDataGridView(DataGridView dataGridView)
{ }

方法中的代码与用于填充datagridview的代码完全相同,只是datagridview的名称更改为您在方法中命名的任何内容。

现在,在您的父窗体中调用此方法。

子窗体通过.ShowDialog()启动,然后在关闭子窗体后立即调用该方法...如下所示:

ChildForm.ShowDialog();

ConnectAndPopulateDataGridView(dataGridView1);

-1
你可以使用SqlDataAdapter来更新DataGridView。
     using (SqlConnection conn = new SqlConnection(connectionString))
        {
            using (SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM Table", conn))
            {
               DataTable dt = new DataTable();
                 ad.Fill(dt);
               dataGridView1.DataSource = dt;
            }
        }

-1

您只需要重新定义数据源。例如,如果您有一个包含a、b和c的DataGridView的DataSource:

DataGridView.DataSource = a, b, c

突然你更新了数据源,只剩下了a和b,你需要重新定义你的数据源:

DataGridView.DataSource = a, b

希望这对你有用。

谢谢。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接