来自BindingSource的C#刷新文本框
我正在刷新使用BindingSource对象的Windows窗体控件时遇到困难。 我们有一个CAB / MVP / SCSF客户端,我(实际上是“我们”,因为它是团队的努力)正在开发,它将与在远程服务器上运行的WCF服务进行交互。 (这是我们的第一次尝试,因此我们处于学习模式)。 其中一个调用(从Presenter)到服务返回一个包含3个DataTable的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 Forms TextBox,MaskedEditBoxes和Infragistics UltraComboEditor Dropdowncombobox我们创建了三个BindingSource对象,每个对象使用VS2008 IDE对应一个DataTable。
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服务来“保存”它。
这是我们的问题。 如果我们选择一个不同的贷款密钥并对服务进行相同的调用并获得一个新的DataSet,再次使用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,但由于DataTable只有一行,我们认为我们不需要它。 网格有很多例子,但我们在这里没有使用。 任何人都可以指出我们哪里出错了,或者指出我们提供更多信息的资源?
我们使用的是VisualStudio 2008,C#和.Net 2.0,XP客户端,W2K3服务器。
提前致谢
维斯
我今天遇到了类似的问题,发现这有效。
private void btnCancel_Click(object sender, EventArgs e) { this.MyTable.RejectChanges(); this.txtMyBoundTextBox.DataBindings[0].ReadValue(); this.EditState = EditStates.NotEditting; }
第一件事:这篇文章需要一些组织。 Pease记得答案没有按顺序排列。 订单由投票决定。
因此,如果您有其他问题,只需修改原始问题(标记为“编辑”以避免混淆)。
Upvote你觉得有用的答案。
哦,顺便说一句,请在包含代码示例时使用代码示例按钮(在编辑窗口上方)。 这将为您提供良好的代码格式,包括语法高亮。
现在到底:你的问题中的根本问题是Binding-Manager保留了与原始对象的链接。
将_ds指定为DataSource时,Binding-Manager将分析DataSet并相应地执行操作。 如果将其他DataSet分配给_ds,则Binding-Manager无法知道这一点。 它仍然具有原始DataSet对象的引用。 这就解释了为什么必须将DataSource属性重置为新的DataSet。
它还解释了为什么删除和添加表不会导致您的预期结果。 同样,Binding-Manager保存对旧表(或该表中第一行)的引用。 新表永远不会受到约束。 同样在这种情况下,_ds的重新分配没有帮助,因为_ds指向与以前相同的DataSet对象。 Binding-Manager足够聪明,可以注意到它是同一个对象,并且没有重新绑定操作。
您必须修改绑定对象的内容(触发Binding-Manager预订的PropertyChanged-Event),或者必须通过为DataSource属性分配不同的对象来触发完全重新绑定。
这是对实际情况的简要描述,但我希望它足以解释和解决您的问题。 不幸的是,我还没有在网上(或其他地方)找到WinForms数据绑定的全面解释。
其他所有情况都失败了,每次收到新数据集时都可以重新分配DataSource,执行以下操作:
bindsrcContract.DataSource = typeof(System.Data.DataSet); bindsrcContract.DataSource = _ds;
(另外,首先初始化DataMember然后DataSource将为您提供更好的性能。)
韦斯,我很高兴能帮忙。 我还记得一个与你非常相似的问题,花了我几个星期的时间在野外弄清楚……
关于你的问题,这就是我所知道的:
-
如果首先设置DataSource,然后设置DataMember,则数据源将被扫描两次,因为设置DataMember随后会更改现有(有效)绑定。 如果你反过来这样做,首先设置DataMember(DataSource为null或更好,typeof(YourData)),绑定只在你设置DataSource时发生一次。
-
我想你可以在这里应用相同的解决方案。 而不仅仅是
bindsrcContract.DataSource = _ds;
在你的最后一行,你应该写
bindsrcContract.DataSource = typeof(System.Data.DataSet); bindsrcContract.DataSource = _ds;
-
很抱歉让我失望,但我从MSDN中了解了所有关于数据绑定以及反复试验的知识。 这真是太痛苦了。 希望其他人可以使用一两个有用的链接。
尝试组合:
bindingsource.EndEdit() // writting data to underlying source bindingSource.ResetBindings(false) // force controls to reread data from bindingSource
每当你给控件写东西时都要用它。