【问题标题】:TextBox change is not saved to DataTable文本框更改未保存到 DataTable
【发布时间】:2012-10-16 22:51:00
【问题描述】:

我在 WinForms 应用程序中进行简单的表格编辑时遇到问题。我一定是错过了一步。

我有一个DataSet,其中包含一个DataTable,它通过SqlDataAdapter 连接到一个数据库。 SqlDataAdapter 上有一个 SqlCommandBuilder。在表单上,​​有TextBoxes 绑定到DataTable。绑定是在 Designer 中完成的,其机器生成的语句如下:

this.tbLast.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.belkData, "belk_mem.last", true));

当我在DataTable 中填写行时,数据库中的值会出现在文本框中,但是当我更改TextBox 的内容时,更改显然不会转到DataTable。当我尝试保存更改时,以下两个都返回 null:

DataTable dtChanges = dtMem.GetChanges();
DataSet dsChanges = belkData.GetChanges();

我忘记了什么?


编辑 - 回复mrlucmorin

保存在一个按钮下。代码是:

    BindingContext[belkData, "belk_mem"].EndCurrentEdit();

    try
    {
        DataSet dsChanges = belkData.GetChanges();
        if (dsChanges != null)
        {
            int nRows = sdaMem.Update(dsChanges);
            MessageBox.Show("Row(s) Updated: " + nRows.ToString());
            belkData.AcceptChanges();
        }
        else { MessageBox.Show("Nothing to save.", "No changes"); }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Error: " + ex.Message);
    }

我已经尝试在不改变行为的情况下放入这些语句:

dtMem.AcceptChanges();
belkData.AcceptChanges();

【问题讨论】:

  • 请告诉我们您的“保存”方法是如何触发的
  • 在您的 TextBox.Validate 事件上添加一个处理程序以确保它通过验证。默认的 DataSourceUpdateMode 是 OnValidation,因此除非您将其更改为 None,否则应在 TextBox Validates 时推送数据

标签: c# winforms data-binding


【解决方案1】:

您的问题只是缺少 5 个字母....您在 dataMember 属性上缺少 .last

BindingContext[belkData, "belk_mem"].EndCurrentEdit();

应该是

BindingContext[belkData, "belk_mem.last"].EndCurrentEdit();

另一种解决方法是使用中介BindingSource 并在调用GetChanges() 之前调用EndEdit()

将您的绑定更改为:

BindingSource bs = new BindingSource();
bs.DataSource = belkData;
tbLast.DataBindings.Add("Text", bs, "belk_mem.last", true);

将保存按钮代码更改为

try
{
    bs.EndEdit(); // needs to be called before getting changes.
    DataSet dsChanges = belkData.GetChanges();
    if (dsChanges != null)
    {
        int nRows = sdaMem.Update(dsChanges);
        MessageBox.Show("Row(s) Updated: " + nRows.ToString());
        belkData.AcceptChanges();
    }
    else { MessageBox.Show("Nothing to save.", "No changes"); }
}
catch (Exception ex)
{
    MessageBox.Show("Error: " + ex.Message);
}

如果您想避免使用中介 BindingSource,也可以只在各个行上调用 EndEdit()

belkData.Rows[0].EndEdit(); 

或者,如果您要处理不止一行

foreach( DataRow row in belkData.Rows )
    row.EndEdit();

对于那些难以理解为什么首先需要调用EndEdit()EndCurrentEdit() 的人。查看Row States and Row VersionsBindingSource.EndEdit Method 上的文档。在您调用EndEdit() 之前,绑定保持在编辑状态,并且更改仅在DataTableProposed 版本中可见。调用 EndEdit() 会将更改移动到 Current 版本。只有这样DataTable 才会“发生变化”。 DbDataAdapter的不看Proposed的版本。

【讨论】:

    【解决方案2】:

    *如果您也使用 BindingSource:只需执行一个简单的 BindingSource.EndEdit(),您的 TextBox 数据就会发送到 DataTable。示例:-

    _bsHeader.EndEdit();
    if (_dsHeader.HasChanges())
    {
        DataTable dsInsert = _dsHeader.GetChanges(DataRowState.Added).Copy();
        _objDal.Insert(dsInsert);
    }
    

    希望这对在这里绊倒的人有所帮助。

    【讨论】:

      【解决方案3】:

      您在创建Binding 实例时缺少DataSourceUpdateMode.OnPropertyChanged

      【讨论】:

      • 这可能不是他想要的行为。默认为 OnValidation,如果 TextBox 未验证,则不会触发。这就是为什么我问他如何调用他的保存方法。
      • 你有错误的想法。 OP 要求更改文本框值时数据表没有得到更新。保存之后。
      • 不,我明白他在说什么。他对 belkData.GetChanges() 的检查肯定是在保存到数据库之前完成的,此时他没有看到对 DataSet 的任何更改。这就是我所说的“保存”方法的意思。而且我想我确切地知道为什么会发生这种情况,我只需要他确认代码被调用的方式和时间。
      • 要确认什么?有一个保存按钮,上面添加了代码。
      • 一个普通的旧 System.Windows.Forms.Button。
      猜你喜欢
      • 1970-01-01
      • 2010-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-10
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      相关资源
      最近更新 更多