如何使用绑定源判断用户是否修改了数据?
我有一个绑定到绑定源的 DataGridView,该绑定源绑定到 List
。用户单击一行,进入带有文本框等的表单。文本框是数据绑定的,如下所示:
if (txtID.DataBindings.Count == 0)
txtID.DataBindings.Add("Text", bindingSource, "Title");
我希望能够检测用户在单击关闭按钮时是否修改了控件中的任何数据,以便我可以提示他们会说“您有未保存的工作。要保存吗?”
如何在绑定源上检测到这一点?
更新:我已经发现我可以执行bindingSource.EndEdit()
,它将更改推送到列表中的项目。在我的项目中,我可以说如果 Dirty 抛出一个消息框,但如果他们单击“否”来保存信息,则 CancelEdit 将不起作用。
I have a DataGridView bound to a bindingsource which is bound to a List<T>
. The user clicks a row that goes to a form with textboxes, etc. The textboxes are databound like so:
if (txtID.DataBindings.Count == 0)
txtID.DataBindings.Add("Text", bindingSource, "Title");
I want to be able to detect if the user has modified any data in the controls when they click the close button, so I can prompt them to say "You have un-saved work. Do you want to Save?"
How do I detect this on the binding source?
UPDATE: I have worked out that I can do bindingSource.EndEdit()
which pushes the changes to my item in the list. In my item, I can then say if Dirty throw a Messagebox but if they click "No" to saving the information, the CancelEdit does not work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
如果列表中的对象支持
INotifyPropertyChanged
事件,并将List
替换为BindingList
您可以订阅ListChanged
事件,用于获取用户所做的任何更改的通知。If your object within the List support the
INotifyPropertyChanged
event and you replace theList<T>
by aBindingList<T>
you can subscribe to theListChanged
event of the BindingList to get informed about any changes made by the user.如果您绑定到 DataSet 那么您很幸运:它有一个 HasChanges 属性。您可以通过对数据集调用 GetChanges 来获取实际更改。这将返回一个新数据集,其中包含所有更改行的副本
If you're bound to a DataSet then you're in luck: it has a HasChanges Property. You can get the actual changes by calling GetChanges on the dataset. This returns a new dataset containing a copy of all changed rows
我现在做了这个功能。你可以这样使用:
I made this function now. You can use like:
在尝试了不同的事情之后,我最终得到了这段代码:
尽管我在 Windows 窗体的实例字段中保存了大量状态信息,但它对我来说工作得很好。但是,使用
CurrentChanged
和CurrentItemChanged
并没有帮助我。After trying different thing I ended up with this piece of code:
It works fine for me, although I save lots of state information in the Windows Form's instance fields. However, twiddling with
CurrentChanged
andCurrentItemChanged
did not help me.一种更简单的方法是订阅 BindingSource 的 ListChanged 事件并根据事件类型设置 IsDirty 标志。
并在事件方法中设置 IsDirty = true...
这里需要注意的是,它无法检测修改后的值何时仍与原始值相同。如果需要该级别的准确性,可以另外使用
Memberwise.Clone
。A simpler approach would be to subscribe to the BindingSource's ListChanged event and set an IsDirty flag based on the event type.
and set IsDirty = true in the event method...
A word of caution here, it would not be able to detect when the modified value is still same as the original value.
Memberwise.Clone
can be used additionally if that level of accuracy is required.我设置了一个相当简单的机制,如下所示:
控制并保存它们的当前值(我执行ReadValue()只是为了
确保我已从字典中的数据源获取值
将控件映射到其值(有一个小方法可以获取
我拥有的每种控件的适当值)。
事件由控件类型决定,但它们都指向
相同的处理程序)
价值。如果不同,那么它会相应地采取行动(在我的例子中
将关闭按钮切换为取消按钮)。如果是一样的话
它检查所有其他绑定控件,以便如果没有
不同的是可以将取消切换回关闭;这是一个很好的功能
当更改被撤消时它也可以识别这种方法,
即使是通过重新输入原始值。
再次绑定控件以执行 WriteValue(),以防万一 WinForms 没有执行
抽出时间去传播一些改变。
如果有人感兴趣,我可以分享来源。
I set up a fairly simple mechanism, as follows:
controls and saves their current values (I do a ReadValue() just to
be sure I've got the values from the DataSource) in a Dictionary
that maps a control to its value (there's a small method that gets
the appropriate value for each kind of control that I have).
event is determined by the type of control, but they all point to
the same handler)
value. If it's different then it acts accordingly (in my case it
switches the Close button for the Cancel button). If it's the same
it checks all the other bound controls, so that if nothing is
different it can switch Cancel back to Close; it's a nice feature of
this method that it also recognizes when a change has been undone,
even if it's by re-entering the original value.
bound controls again to do WriteValue(), just in case WinForms didn't
get around to propagating some change.
I can share the source if anyone is interested.
如果您的绑定源使用数据表,您可以这样做:
If your bindingsource uses a datatable you can do this :
我知道这是一篇旧文章,但这里有一个带有 IsDirtyFlag 的扩展 BindingSource - 您可以按照自己的意愿调整它 - 我几年前从网络上的另一个帖子中提取了此代码 - 做了一些非常小的更改,我认为它最初是在VB - 我转换为 C# ..
I know this is an old post but here is an Extended BindingSource with IsDirtyFlag - you can adapt it how you would like - I pulled this code from another posting somewhere on the net years ago - made some very minor changes I think it was originally in VB - I converted to C# ..
从我更新的问题中,我发现我必须使用 Memberwise.Clone 在 BeginEdit 中存储对象的当前版本,然后在 CancelEdit 中将其恢复到当前版本。
From my updated question I found I had to store a current version of the object at BeginEdit using Memberwise.Clone and then in CancelEdit I restored that to the current.
我总是做的是捕获控件的各个“更改”事件。在下面的示例中,我在本示例中使用了选项卡控件。 Try/Catch 是一个肮脏的解决方案,因为不必处理各种异常;-)
What I always do is to capture the individual "changed" events of the controls. In the below example I used a tabcontrol in this example. The Try/Catch is a dirty solution for not having to deal with all kinds of exceptions ;-)
我不确定在提出问题时它是否可用,但我使用 grid_CurrentCellDirtyStateChanged;事件
I aren't sure if it was available when the question was asked but I use the grid_CurrentCellDirtyStateChanged; event
首先确保您设置了 DataSourceUpdateMode.OnPropertyChanged
然后添加将此代码添加到您的 movenext 点击事件中
first make Sure you set DataSourceUpdateMode.OnPropertyChanged
then add add this code to your movenext click event