【问题标题】:Datagridview doesn't refresh even after reassigning its datasource to bindingsource即使将其数据源重新分配给 bindingsource,Datagridview 也不会刷新
【发布时间】:2016-03-20 00:04:08
【问题描述】:

我有 3 个不同的数据网格视图都绑定到一个单独的绑定源。当新数据加载到绑定源中时,我想更新数据网格视图。我在这里尝试了解决这个问题的普遍接受的方法:

1.) 创建绑定源

2.) 将此对象的数据源设置为您的数据集表。

3.) 将 DatagridView 的数据源设置为绑定源对象。

bindingsrc.DataSource = newDataTable;

// The two lines below were supposedly a dirty solution to refreshing the grid.

dg1.DataSource = null;
dg1.DataSource = bindingsrc;

但是它不起作用。我还尝试为每个绑定源重置绑定:

bindingsrc.ResetBindings();

但无济于事。我知道我得到了正确的新数据,因为一旦我在调试时进入代码,newDataTable 就有正确的新数据。所以这是datagridview不刷新的问题。如果这可能是相关的,我的数据网格视图是面板的一部分,其父级是拆分容器。我也尝试过刷新父:

this.dataGridView.Parent.Refresh()

没有任何结果。

【问题讨论】:

  • 试试“dg1.Refresh();”
  • 我看不到这样命名的函数。
  • 也试过了,可惜没用。
  • 您可以尝试先刷新DataGridView,然后再刷新父级吗?
  • datagridview 仍然没有刷新。

标签: c# .net vb.net winforms datagridview


【解决方案1】:

我找到了解决问题的方法。我不需要处理 BindingContext_Changed 事件,一般方法如下:

bindingSource1.ResetBindings(false);
dataGridView1.DataSource = null;
bindingSource1.DataSource = null;
bindingSource1.DataSource = mytable;
dataGridView1.DataSource = bindingSource1;

是更新网格的正确方法。

真正的问题:来自我最初的问题:“如果这可能相关,我的数据网格视图是面板的一部分,其父级是拆分容器。”以下代码行:

 split.Panel2.Controls.Add(new ConfigurableMatrices(comboBox1.SelectedItem.ToString(), comboBox2.SelectedItem.ToString())); 

正在将此类(ConfigurableMatrices,其中包含我的 datagridviews)及其所有控件重新添加到 splitcontainer 父级的第二个面板。这行代码是从 splitcontainer 的另一半执行的。之后我也神清气爽:

split.Panel2.Controls.Add(new ConfigurableMatrices(comboBox1.SelectedItem.ToString(),  
comboBox2.SelectedItem.ToString()));
split.Panel2.Refresh();

但是这样,我每次只在顶部添加一个新类(ConfigurableMatrices),并且由于某种原因没有正确更新。现在适合我的解决方案是在上述两行代码之前调用 Dispose 方法:

foreach (Control control in split.Panel2.Controls)
        {
            control.Dispose();
        }
split.Panel2.Controls.Add(new ConfigurableMatrices(comboBox1.SelectedItem.ToString(), comboBox2.SelectedItem.ToString()));
split.Panel2.Refresh();

我希望 Dispose 方法是解决此问题的正确方法,并且不会在未来引发其他问题。

【讨论】:

  • dataGridView1.DataSource = null; 帮了我大忙,我在设置的地方添加了这个。
【解决方案2】:

一般情况下不需要刷新。下面打开一个 Microsoft NorthWind 数据库,将所有表名加载到具有 DropDownStyle = DropDownList 的 ComboBox 中。在 ComboBox 中选择一个表名,按下按钮,然后我们的 DataGridView 被加载。我绕过了使用 DataSet ,但除了 DataGridView 的 DataMember 属性之外,这不会产生任何影响,如果没有设置可能会导致手头的问题,因此最好检查 Datamember 是否正确。

获取表名并为我们提供连接字符串的代码,无论是 .accdb 还是 .mdb

在此代码中,我们使用 SELECT *,但当然在实际应用中,我们单独选择特定操作所需的字段,除非需要查看所有字段。

Imports System.Data.OleDb
Public Class SchemaInfo
    Private Shared _Instance As SchemaInfo
    Public Shared Function GetInstance() As SchemaInfo
        If _Instance Is Nothing Then
            _Instance = New SchemaInfo
        End If
        Return _Instance
    End Function
    Protected Sub New()
    End Sub
    Private Shared _ConnectionString As String
    Public Function ConnectionString() As String
        Return _ConnectionString
    End Function
    Public Function TableNames(ByVal DatabaseName As String) As List(Of String)
        Dim Names As New List(Of String)

        Using cn As New OleDbConnection(BuildConnectionString(DatabaseName))
            _ConnectionString = cn.ConnectionString
            cn.Open()

            Dim dt As DataTable = cn.GetSchema("Tables", New String() {Nothing, Nothing, Nothing, "Table"})

            For Each row As DataRow In dt.Rows
                Names.Add(row.Field(Of String)("Table_Name"))
            Next

        End Using

        Return Names

    End Function
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Shared Function BuildConnectionString(ByVal DatabaseName As String) As String

        If IO.Path.GetExtension(DatabaseName).ToLower = ".accdb" Then

            Dim Builder As New OleDb.OleDbConnectionStringBuilder With
                {
                    .Provider = "Microsoft.ACE.OLEDB.12.0",
                    .DataSource = DatabaseName
                }

            Return Builder.ConnectionString

        ElseIf IO.Path.GetExtension(DatabaseName).ToLower = ".mdb" Then

            Dim Builder As New OleDb.OleDbConnectionStringBuilder With
                {
                    .Provider = "Microsoft.Jet.OLEDB.4.0",
                    .DataSource = DatabaseName
                }

            Return Builder.ConnectionString

        Else

            Throw New Exception("File type not supported")

        End If

    End Function
End Class

表格代码

Imports System.Data.OleDb

Public Class SwitchTableOnBindingSourceForm
    WithEvents bsData As New BindingSource
    Private Sub SwitchTableOnBindingSourceForm_Load(
        sender As Object, e As EventArgs) Handles MyBase.Load

        cboTables.DataSource = SchemaInfo.GetInstance.TableNames(
            IO.Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, "NorthWind.accdb"))

        DataGridView1.DataSource = bsData

    End Sub
    Private Sub cmdSelectTable_Click(
        sender As Object, e As EventArgs) Handles cmdSelectTable.Click

        Dim dt As New DataTable
        Using cn As New OleDbConnection(SchemaInfo.GetInstance.ConnectionString)
            Using cmd As New OleDbCommand("SELECT * FROM " & cboTables.Text, cn)
                cn.Open()
                dt.Load(cmd.ExecuteReader)
            End Using
        End Using

        bsData.DataSource = dt

    End Sub
End Class

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 2010-09-20
    • 2021-09-15
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2017-11-28
    相关资源
    最近更新 更多