应如何判断用户是否通过交互式操作而弄“脏”了界面中绑定的数据?

zhoupc88 2010-01-27 12:57:35
在WinForm的设计中,需要判断用户是否通过界面中的控件修改了其所绑定的数据,即为“弄脏了界面”。如果弄脏了,就要即时将导航工具栏中的“新增”、“删除”按钮标签切换为“保存”和“还原”。

为达到此目的,在TextBox、ComboBox的TextChanged事件,在NumericUpDown、DateTimePicker控件的ValueChanged事件,在CheckBox控件的CheckStateChanged事件,在RadioButton控件的CheckedChanged事件,以及在DataGridView控件的CurrentCellDirtyStateChanged事件中编写代码,调用把界面弄脏的处理方法:MakeFormDirty()。

但这样做有个问题:固然用户的交互式修改会触发这些事件,但是在窗体加载时、乃至记录的翻页导航时也同样会触发这些事件。因而,要想在这些非交互式修改的情况下不引起导航工具栏状态的切换,就不得不在窗体加载、记录翻页等过程完成时,加上一句把工具栏变回“干净”状态的语句。如此虽然“解决”了问题,但一来似乎有点麻烦,二来自我老是感觉方法似乎不太地道。

请问:这是否是最好、或者说唯一的解决办法了?

在那些××Changed事件中编写代码来处理这件事,是否是正确的和合适的?
...全文
157 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
monkchen 2010-01-29
  • 打赏
  • 举报
回复
很现实的问题,不过确实没有通用的好办法,特定的场景只能有特定的方法:

如果绑定的数据源是由Entity Framework自动生成的实体类,那么这个问题很简单,其生成的实体类都派生自EntityObject,而EntityObject有个PropertyChanged事件,任何一个属性被更改都会触发该事件。。。 对你来说这个是福音

如果是自定义实体类,那么可以模仿Entity Framework,给你的实体类也定义一个PropertyChanged事件,在类的每个Property 的set里面触发该事件,这样无论是数据感知控件还是代码修改任何属性,你都可以捕捉到。

如果数据来源是DataTable, 这个我基本没用过,不过还是帮你查了MSDN,ColumnChanged、RowChanged事件应该可以利用起来

zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
我用的正是××Changed事件,但提出的问题是:不止是用户的交互式修改会触发这些事件,而且在窗体加载时、乃至记录的翻页导航时也同样会触发这些事件。而我只想要用户的交互式修改,不要其他的。
波导终结者 2010-01-27
  • 打赏
  • 举报
回复
控件有changed事件,数据源有rowstate属性
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
可如果放在Validated事件的话,判断不出用户在离开那个控件之前,是否曾经“改”了那个控件的数据呀。如果仅仅在那个控件停留过、而没有修改,那么是不需要把工具栏变“脏”的。
rain1154598 2010-01-27
  • 打赏
  • 举报
回复
试试放到
Validated 事件里呢?
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
感谢您的详尽解答!

不过因为之前没有了解过,所以只能看得模模糊糊,不太明白。只能以您的解答为契机和线索,另外上网搜索了。
Dobzhansky 2010-01-27
  • 打赏
  • 举报
回复
winform 的数据绑定是在 数据 <-> 控件属性 之间建立了一个双向的绑定关系

修改任何一方, 另一方有绑定机制来保证同步.

其实这也是通过订阅变更事件来实现的.

即使你不使用她, 了解一下对自己的设计实现也是有好处的.

绑定有 3 类:
简单绑定: 数据字段到单个属性的绑定, 如 TextBox 的 Text 属性绑定到 字段
查询绑定: 单个字段绑定 + 查询数据的绑定, 典型的是 ComboBox
复杂绑定: 一个控件本身消费数据源, 内部负责绑定的, 如 DataGridView.
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
还是没太懂,dobzhansky大侠,能否以简单实例说明一二?
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dobzhansky 的回复:]
你要重新实现 winform 的 数据绑定机制
[/Quote]
能否请您说得更明白一点点?不胜感谢!
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 dobzhansky 的回复:]
winform 的 data binding 你再深入一下?
[/Quote]
谢谢!不过能否请您再说得更明确一点?
Dobzhansky 2010-01-27
  • 打赏
  • 举报
回复
你要重新实现 winform 的 数据绑定机制
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 sp1234 的回复:]
流行几十年的MVC就是一种简单有效的观念。界面的显示来自于数据模型,但是界面上的改变事件不能直接修改界面其它部分,而是只能去改变数据模型。
界面和数据之间可以双向沟通,而界面和界面之间则不允许私自沟通。
你就是因为界面和界面之间私通太多了,麻烦扩展得太快了。
[/Quote]
谢谢!

但我还是没有明白:您的意思是指这种用户在界面上一修改数据、导航工具栏就立即随之切换状态,这种设计本身都是要不得的不良设计?还是指实现这种设计目的,有更好的方法?如果是后者的话,那方法又应该是什么呢?
wangping06 2010-01-27
  • 打赏
  • 举报
回复
mark
zhoupc88 2010-01-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tchjl2007 的回复:]
把修改过的行先保存至数组中 然后通过操作一并提交
[/Quote]
没看明白。我遇到的不是如何能保存数据的问题,而是如何判断用户操作修改了界面中的数据,从而可以即时将导航工具栏状态作相应的切换。
Dobzhansky 2010-01-27
  • 打赏
  • 举报
回复
winform 的 data binding 你再深入一下?
  • 打赏
  • 举报
回复
流行几十年的MVC就是一种简单有效的观念。界面的显示来自于数据模型,但是界面上的改变事件不能直接修改界面其它部分,而是只能去改变数据模型。

界面和数据之间可以双向沟通,而界面和界面之间则不允许私自沟通。

你就是因为界面和界面之间私通太多了,麻烦扩展得太快了。
Hamsic 2010-01-27
  • 打赏
  • 举报
回复
把修改过的行先保存至数组中 然后通过操作一并提交

111,120

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧