【问题标题】:Why does my DataGridview refuse to refresh?为什么我的 DataGridview 拒绝刷新?
【发布时间】:2012-04-05 03:34:15
【问题描述】:

我正在更新表格中的一行。表的子集显示在 DataGridView 中。当我更新行时,更改不会反映在 DataGridView 中。即使我在打电话 DataGridView.Invalidate() 和 DataGridView.Refresh() 提交更改后,我必须关闭应用程序,重新启动,然后重新运行查询才能看到更改。

相关代码为:

private void buttonUpdate_Click(object sender, EventArgs e)
{
    const int TICKETID_COLUMN = 0;

    String _ticketID = dataGridView1.CurrentRow.Cells[SOME_COLUMN].Value.ToString();

    UpdateRecord(_ticketID, textBoxTicketSource.Text,
                textBoxAboutSomeID.Text, textBoxCategoryID.Text, textBoxContactEmail.Text);
}

private void UpdateRecord(string ATicketID, string ATicketSource, string 
    AAboutSomeID, string ACategoryID, string AContactID)
{
    oracleConnection1.Open();
    OracleCommand ocmd = new OracleCommand();
    OracleTransaction ot;
    // Start a local transaction 
    ot = oracleConnection1.BeginTransaction(System.Data.IsolationLevel.ReadCommitted);
    // Assign transaction object for a pending local transaction 
    ocmd.Transaction = ot;
    ocmd.Connection = oracleConnection1;
    try
    {
        ocmd.CommandText = @"UPDATE ABC.CONCERTTICKETS 
                                     SET TICKETSOURCE = :p_TICKETSOURCE, 
                                     ABOUTSOMEID = :p_ABOUTSOMEID, 
                                     CATEGORYID = :p_CATEGORYID, 
                                     CONTACTEMAIL = :p_CONTACTEMAIL 
                                     WHERE TICKETID = :p_TICKETID";
        ocmd.Parameters.Add("p_TICKETSOURCE", ATicketSource);
        ocmd.Parameters.Add("p_ABOUTSOMEID", Convert.ToInt32(AAboutSOMEID));
        ocmd.Parameters.Add("p_CATEGORYID", Convert.ToInt32(ACategoryID));
        ocmd.Parameters.Add("p_CONTACTEMAIL", AContactID);
        ocmd.Parameters.Add("p_TICKETID", ATicketID);
        ocmd.ExecuteNonQuery();
        ot.Commit();

        Popul8TheGrid();

        dataGridView1.Invalidate();
        dataGridView1.Refresh();
    }
    catch (Exception e)
    {
        ot.Rollback();
        throw;
    }
    finally
    {
        oracleConnection1.Close();
    }
}

private void Popul8TheGrid()
{
    int iFromYear = dateTimePickerFrom.Value.Year;
    int iFromMonth = dateTimePickerFrom.Value.Month;
    int iFromDay = dateTimePickerFrom.Value.Day;
    int iToYear = dateTimePickerTo.Value.Year;
    int iToMonth = dateTimePickerTo.Value.Month;
    int iToDay = dateTimePickerTo.Value.Day;

    oracleCommand1.Parameters.Clear();
    oracleCommand1.Parameters.Add("iStartDate", new DateTime(iFromYear, iFromMonth, 
        iFromDay));
    oracleCommand1.Parameters.Add("iEndDate", new DateTime(iToYear, iToMonth, 
        iToDay));
    oracleCommand1.Parameters.Add("iCATEGORYID", 114);
    // OracleRef is apparently like OracleDbType.RefCursor;
    OracleRef or = new OracleRef("_or");
    oracleCommand1.Parameters.Add("cref", or);

    oracleConnection1.Open();

    oracleDataAdapter1.SelectCommand = oracleCommand1;
    oracleDataAdapter1.GetFillParameters();
    oracleDataAdapter1.Fill(oracleDataTable1);
    dataGridView1.DataSource = oracleDataTable1;

    oracleConnection1.Close();
}

更新:

根据 Hall 的建议(我尝试用评论回复,但似乎挂了):

好的,我现在知道了:

        oracleDataAdapter1.SelectCommand = oracleCommand1;
        oracleDataAdapter1.GetFillParameters();
        oracleDataAdapter1.Fill(oracleDataTable1);
        // I don't see a "Clear" method or some such...
        dataGridView1.DataSource = null;
        //dataGridView1.DataSource = oracleDataTable1;

        BindingSource b = new BindingSource(); 
        b.DataSource = oracleDataTable1; 
        dataGridView1.DataSource = b;
        b.ResetBindings(false);

        oracleConnection1.Close();

...它仍然工作相同 - 更新,但 DataGridView 直到我重新启动应用程序才知道它。

【问题讨论】:

  • 那么你居然把grid的datasource设置为null,每次新建一个bindingsource,绑定binding source到toe datagridview,然后resetbindings,你的grid还是没有显示新数据?你的代码发生了一些非常奇怪的事情,因为你的步骤实际上是多余的——你不应该需要其中的一半来工作。如果您使用调试器单步执行,您会在数据表中看到什么?如果将绑定源提升到类级别变量然后只更新数据表而不是完全重新创建它会发生什么?

标签: c# .net oracle datagridview dotconnect


【解决方案1】:

Invalidate() 和 Refresh() 不重新查询数据源的原因是它们仅适用于图形方面 - 它们都使控件的客户区无效并强制重新绘制,但问题是是底层控件认为它的数据源没有任何变化,因为它依赖数据源来告诉它什么时候发生。

您需要的是您的DataSource 能够告诉DataGridView 正在发生的事情,例如BindingList<T> 或BindingSource,两者都有ListChanged 事件@987654328 @订阅。

我原以为DataTable 也会在网格发生变化时通知网格,但我要么弄错了,要么OracleDataTable 不同。

解决问题的方法是引入BindingSource 并将其作为DataGridView 的数据源。然后让你的OracleDataTable成为绑定源的数据源。如果这不起作用,您可以在绑定源上调用ResetBindings() 方法。

BindingSource b = new BindingSource();
b.DataSource = oracleDataTable1;
dataGridView1.DataSource = b;

【讨论】:

    【解决方案2】:

    尝试做:

    dataGridView1.DataSource = null;
    dataGridView1.DataSource = oracleDataTable1;
    

    【讨论】:

    【解决方案3】:
    dataGridView1.DataSource = null;
    dataGridView1.DataBind();
    dataGridView1.DataSource = oracleDataTable1;
    dataGridView1.DataBind();
    

    【讨论】:

    • DataGridView 没有 DataBind() 方法:“System.Windows.Forms.DataGridView”不包含“DataBind”的定义,并且没有扩展方法“DataBind”接受类型的第一个参数可以找到“System.Windows.Forms.DataGridView”(您是否缺少 using 指令或程序集引用?)
    • DataBind 是来自 Asp.Net gridview 控件的方法,而不是 winforms DataGridView。
    • 你试过.Refresh()或.Update()吗?
    猜你喜欢
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多