【问题标题】:C# refreshing textbox from BindingSourceC# 从 BindingSource 刷新文本框
【发布时间】:2008-10-28 20:01:19
【问题描述】:

我在刷新使用 BindingSource 对象的 Windows 窗体控件时遇到了困难。我们有一个 CAB/MVP/SCSF 客户端,我(实际上是“我们”,因为它是一个团队的努力)正在开发它将与远程服务器上运行的 WCF 服务进行交互。 (这是我们第一次尝试,所以我们处于学习模式)。对服务的调用之一(来自 Presenter)返回一个包含 3 个 DataTables 的 DataSet,名为“Contract”、“Loan”和“Terms”。每个表只包含一行。当服务返回数据集时,我们将其存储在 SmartPart/View 中的类成员变量中,方法是调用视图中称为 BindData() 的函数并将数据集从演示者类传递给视图;

private System.Data.DataSet _ds = null;
public void BindData(System.Data.DataSet ds)
{
    string sErr = "";
    try
    {
        _ds = ds;  // save to private member variable

        // more code goes down here
    }
}

我们正在尝试将三个 DataTable 中的每一个绑定到各种 Windows 窗体 TextBox、MaskedEditBox 和 Infragistics UltraComboEditor Dropdown 组合框我们创建了三个 BindingSource 对象,每个 DataTable 使用 VS2008 IDE。

private System.Windows.Forms.BindingSource bindsrcContract;
private System.Windows.Forms.BindingSource bindsrcLoan;
private System.Windows.Forms.BindingSource bindsrcTerms;

我们正在绑定这样的值

if (bindsrcContract.DataSource == null)
{
    bindsrcContract.DataSource = _ds;
    bindsrcContract.DataMember = “contract”;

    txtContract.DataBindings.Add(new Binding("Text", bindsrcContract, "contract_id", true));                       

    txtLateFeeAmt.DataBindings.Add(new Binding("Text", bindsrcContract, "fee_code", true));

    txtPrePayPenalty.DataBindings.Add(new Binding("Text", bindsrcContract, "prepay_penalty", true));

    txtLateFeeDays.DataBindings.Add(new Binding("Text", bindsrcContract, "late_days", true));
}

if (bindsrcLoan.DataSource == null)
{
    bindsrcLoan.DataSource = _ds;
    bindsrcLoan.DataMember = “loan”;

    mskRecvDate.DataBindings.Add(new Binding("Text", bindsrcLoan, "receive_date", true));

    cmboDocsRcvd.DataBindings.Add(new Binding("Value", bindsrcLoan, "docs", true));     
}

当我们第一次从服务中读取数据并取回数据集时,这很有效。信息显示在表单的控件上,我们可以使用表单对其进行更新,然后通过将更改后的值传递回 WCF 服务来“保存”它。

这是我们的问题。如果我们选择一个不同的贷款密钥并对服务进行相同的调用并获得一个新的数据集,同样有 3 个表,每个表有一行,控件(文本框、屏蔽编辑框等)不会使用新信息更新.请注意,smartPart/View 没有关闭或关闭,而是在调用服务之间保持加载。在第二次调用中,我们没有重新绑定调用,而只是尝试从更新的 DataSet 中刷新数据。

我们已经尝试了我们能想到的一切,但显然我们遗漏了一些东西。这是我们第一次尝试使用 BindingSource 控件。我们试过了

bindsrcContract.ResetBindings(false);

bindsrcContract.ResetBindings(true);

bindsrcContract.RaiseListChangedEvents = true;

for (int i = 0; i < bindsrcContract.Count; i++)
{
    bindsrcContract.ResetItem(i);
}

以及再次重置 DataMember 属性。

bindsrcContract.DataMember = ”Contract”;

我们看过很多例子。许多示例都引用了 BindingNavigator,但由于 DataTables 只有一行,我们认为我们不需要它。有很多关于网格的例子,但我们在这里没有使用一个。谁能指出我们哪里出了问题,或者向我们指出可以提供更多信息的资源?

我们使用 VisualStudio 2008、C# 和 .Net 2.0、XP 客户端、W2K3 服务器。

提前致谢

韦斯

【问题讨论】:

    标签: c# textbox bindingsource


    【解决方案1】:

    我今天遇到了类似的问题,发现这个可行。

    private void btnCancel_Click(object sender, EventArgs e)
    {
        this.MyTable.RejectChanges();
        this.txtMyBoundTextBox.DataBindings[0].ReadValue();
        this.EditState = EditStates.NotEditting;
    }
    

    【讨论】:

      【解决方案2】:

      第一件事:这篇文章需要整理一下。请记住,答案不是按顺序排列的。顺序由投票决定。

      因此,如果您还有其他问题,只需修改您原来的问题(用“编辑”标记以避免混淆)。

      点赞你认为有用的答案。

      哦,顺便说一句,在包含代码示例时,请使用代码示例按钮(在编辑窗口上方)。这会给你很好的代码格式,包括语法高亮。

      现在开始:两个问题的根本问题是 Binding-Manager 保留了指向原始对象的链接。

      当您将 _ds 指定为 DataSource 时,Binding-Manager 会分析 DataSet 并采取相应措施。如果您将一些其他 DataSet 分配给 _ds,则 Binding-Manager 无法知道这一点。它仍然具有对原始数据集对象的引用。所以这就解释了为什么必须将 DataSource 属性重置为新的 DataSet。

      它还解释了为什么删除和添加表格不会导致您的预期结果。同样,Binding-Manager 保存对旧表(或该表中的第一行)的引用。新表永远不会绑定。同样在这种情况下,重新分配 _ds 也无济于事,因为 _ds 指向与以前相同的 DataSet 对象。 Binding-Manager 足够聪明,可以注意到它是同一个对象并且不执行重新绑定操作。

      您要么必须修改绑定对象的内容(这会触发 Binding-Manager 订阅的 PropertyChanged-Event),要么必须通过将不同的对象分配给 DataSource-property 来触发完整的重新绑定。

      这是对实际情况的简化描述,但我希望它足以解释和解决您的问题。不幸的是,我还没有在网络上(或其他地方)找到关于 WinForms 数据绑定的全面解释。

      【讨论】:

      • TToni,感谢您的有用解释。顺便说一句,OP 不能在 11(或 1,在重新注册后)声望点上投票;)
      【解决方案3】:

      如果所有其他方法都失败,您可以在每次收到新数据集时重新分配 DataSource,执行以下操作:

      bindsrcContract.DataSource = typeof(System.Data.DataSet);
      bindsrcContract.DataSource = _ds;
      

      (另外,先初始化 DataMember 再初始化 DataSource 会带来更好的性能。)

      【讨论】:

        【解决方案4】:

        韦斯,我很高兴能帮上忙。我仍然记得一个与你的问题非常相似的问题,我花了数周时间才弄清楚......

        关于您的问题,我知道的只有以下内容:

        1. 如果您先设置 DataSource,然后设置 DataMember,您的数据源将被扫描两次,因为设置 DataMember 随后会更改现有(有效)绑定。如果反过来,首先设置 DataMember(DataSource 为 null 或更好,typeof(YourData)),绑定只会在设置 DataSource 时发生一次。

        2. 我认为您可以在这里应用相同的解决方案。而不仅仅是

          bindsrcContract.DataSource = _ds;
          

          在你的最后一行,你应该写

          bindsrcContract.DataSource = typeof(System.Data.DataSet);
          bindsrcContract.DataSource = _ds;
          
        3. 很抱歉让我失望了,但我从 MSDN 以及反复试验中了解到了所有关于数据绑定的知识。这很痛苦。希望其他人可以提供一两个有用的链接。

        【讨论】:

          【解决方案5】:

          尝试组合:

          bindingsource.EndEdit() // writting data to underlying source 
          bindingSource.ResetBindings(false)  // force controls to reread data from bindingSource
          

          每当您向控件写入内容时使用它。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-12-21
            • 2020-06-13
            • 1970-01-01
            • 2013-07-08
            • 2021-11-08
            • 1970-01-01
            • 2012-03-07
            • 1970-01-01
            相关资源
            最近更新 更多