上一篇,开始了采购订单的开发,谈完 Combo Box 怎样绑定到 ViewModel 的集合,还把选定项的其他信息一并显示在 View 的另一个控件(TextBlock)。这次继续谈表头的部分,和介绍明细行的绑定。

由于单纯把单一个普通控件绑到 ViewModel 属性比较简单,我只介绍一个,其他的请自行看代码。

VIEWMODELS

就拿单据号来看看。它在 View 上是一个 TextBox,在 Model 内是 string,没有比这更简单的了。以下是 View 的 XAML:

然后是 ViewModel 的相关代码:

代码是接着上一篇来写下去的。上次的部分我收了起来,需要的请看上一篇。

这里实在没有什么好说的,唯一的是,我在 get 和 set 都直接读取或写入业务类实例的属性内,这免去了一层映射。不喜欢把 Model 类直接暴露到 View 的,不喜欢我这方式的,就只能在 ViewModel 多保存一个private/internal string,在保存或更新时候你自己映射到 Model 实例。绝大多数情况中,我认为没有这必要这样分隔。

然后,我直接谈谈明细行了。它有好几个有趣的地方。

首先是添加、删除行按钮。其实很多第三方控件,都已经有这些功能,而且实现得比我这样写好很多,比如,右击带出菜单来删行,最后一行有个添加行按钮等等。要我自己弄到那样要花点功夫,而且跑题了。就先这样吧。

说 WPF 一切都绑定。是的,连命令也可以绑定。看看这两个按钮的 XAML:

如果你过往用 Win Form,现在用 WPF 而且正在学习 MVVM,最好是把 WinForm 的一切忘掉。Button 的命令不是双击设计界面生成句柄来做的,是上面这做法。Command 绑定,要求是绑到实现了 ICommand 接口的实例,在我第一篇已经提到过 RelayCommand,你可以用它,或者你喜欢的用别的也行,比如 DelegateCommand。

按照上面 XAML 的写法,意思是 DataContext,即 ViewModel 内,有两个 public 属性 (AddRowCommand / DeleteRowCommand),它们都是实现了 ICommand 接口的。那么,看看 ViewModel 代码,先看看 AddRowCommand,用来添加新明细行的:

有人不喜欢我这种写法,他们喜欢在 ViewModel 的构造函数,初始化时候,把 addRowCommand 通通创建实例先,get 内直接返回 addRowCommand。我没觉得有什么明显分别,你喜欢。

由于上一篇的代码内,已经写了,PoDetails 是 ObserverableCollection<T>,所以当你用代码添加行时候,视图会收到通知,就会更新显示。单纯用 List 之类来做 PoDetails 集合,或者其他没有实现 INotifyCollectionChanged 的集合,是做不到这效果的。

第一篇也已经提到,RelayCommand 的设计,当构造函数是一个参数时候,CanExecute 永远返回 True,这命令是永远都能执行,Button 永远都是 enable 的。要 disable 的时候,做法可以看看我 ViewModel 的另一个 ICommand 属性,DeleteRowCommand:

当我没有点击任何行,没有选任何行,我希望“删除行”按钮被禁用,disable,灰色。要做到这效果,我需要知道用户有没有选择了 GridView 内的行。所以我加了一个属性来记录当前选定的行,是哪个,它的类型,当然是行记录业务对象 PurchaseOrderDetail:

只要把 GridView 的选中行,绑到 CurrentRow,然后让deleteRowCommand 内 CanExecute 委托(构造函数第二个参数)来检查 CurrentRow 是否为空 null,就能做到了。GridView 的选中行,绑到 CurrentRow 的 XAML 代码如下:

另外有了 CurrentRow,删除行时候视图触发命令时候,也不需要参数,不用告诉 ViewModel 当前行是哪个,因为当前行就是 CurrentRow。要删除它,就像 ViewModel 的 DeleteRow() 第 130 行代码那样,直接 remove() 它即可。

由于 CurrentRow 为 null 时候(用户没有选任何行的时候),deleteRowCommand 的 CanExecute 会返回 False,这命令是无法执行的,界面按钮是 disable 状态,所以在 DeleteRow 连检查 CurrentRow 是否为空等的代码也可以省掉了。代码能运行到 DeleteRow() 时候,CurrentRow 必定有值,remove 代码不会抛异常。

说了半天,给大家看看效果图:

没有任何行的时候

添加了行,但 GridView 没有焦点,没选行的时候

添加了行,选中了的时候

删除了行,没有再次选中行的时候

ViewModel 代码的文本,我下一次才贴出来,那样比较完整。

接下去,下一次,会讲物料号的绑定。它的特别之处,在于物料号是选项,选项列表来自系统的 Inventory 集合,这集合,是所有明细行共用的,不是一行一个新集合。MVVM 模式下,怎样能做到?下回介绍。

我在这群里,欢迎加入交流:
开发板玩家群 578649319
硬件创客 (10105555)

转载于:https://www.cnblogs.com/leptonation/archive/2012/05/10/2493612.html

C# WPF MVVM 实战 – 2.2相关推荐

  1. C# WPF MVVM 实战 – 3 – 树结构

    树结构放在 WPF ,有大家熟悉的 TreeView.Menu / MenuItem 等等,自定义的话它是 HierarchicalDataTemplate. 用上 MVVM 模式,视图与数据分离,意 ...

  2. C# WPF MVVM项目实战(进阶②)

    这篇文章还是在之前用Caliburn.Micro搭建好的框架上继续做的开发,今天主要是增加了一个用户窗体ImageProcessView,然后通过Treeview切换选择项之后在界面显示不同效果的图片 ...

  3. C# 值得永久收藏的WPF项目实战(经典)

    01 - 简介 之前也写过好多篇CM框架相关的项目实战文章,比如: C# WPF框架Caliburn.Micro快速搭建 C# WPF框架Caliburn.Micro入门实例1 C# WPF MVVM ...

  4. C# WPF MVVM模式Prism框架下事件发布与订阅

    01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Prism提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间通过事 ...

  5. C# WPF MVVM模式Prism框架从零搭建(经典)

    01 - 前言 目前最新的PRISM的版本是8.1.97,本节以6.3.0.0 讲解,可以在Github上获取PRISM的源码. Prism Github地址:https://github.com/P ...

  6. WPF MVVM 弹框之等待框

    WPF MVVM 弹框之等待框 目录 一.效果 二.弹框主体改造 三.等待动画用户控件 四.弹窗 ViewModel 和帮助类的改造 五.使用方法和代码地址 独立观察员 2020年10月13日 之前写 ...

  7. C# WPF MVVM模式Caliburn.Micro框架下事件发布与订阅

    01 - 前言 处理同模块不同窗体之间的通信和不同模块之间不同窗体的通信,Caliburn提供了一种事件机制,可以在应用程序中低耦合的模块之间进行通信,该机制基于事件聚合器服务,允许发布者和订阅者之间 ...

  8. WPF MVVM从入门到精通1:MVVM模式简介

    WPF MVVM从入门到精通1:MVVM模式简介 原文:WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录 ...

  9. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍...

    WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正 ...

  10. (WPF, MVVM) Event 处理

    原文:(WPF, MVVM) Event 处理 WPF的有些UI元素有Command属性可以直接实现绑定,如Button 但是很多Event的触发如何绑定到ViewModel中的Command呢? 答 ...

最新文章

  1. 基本表改变视图不改变为什么_中国白酒包装是真的很丑吗,为什么不改变包装?...
  2. tensorflow中的seq2seq例子为什么需要bucket? 有关tensorflow 的sequence2sequence例子,为什么需要用到buckets,rnn不是可以处理任意长度的数据吗
  3. 限制网速 制造测试条件
  4. TensorFlow(一)
  5. 适配Win11!Edge重磅更新来袭
  6. find命令 -- 之查找指定时间内修改过的文件
  7. [已解决]fdfs-client-py==1.2.6安装失败
  8. AE安装部署以及监测ArcEngine runtime 9.3是否安装
  9. 泡泡玛特回应与肯德基联名引发炒作:暂停食品行业的定制盲盒业务
  10. android调用文件管理器回调,Android中调用系统管理器选择文件并返回绝对路径
  11. even though和even if的区别
  12. 数据库学习----JDBC
  13. 三角函数π/2转化_1道真题,串讲三角函数图像与恒等变换,兼谈选择题的构思原则 | 真题精讲22...
  14. 做出胶卷的效果——图片循环滚动播放
  15. 预防抑郁的简单技巧:每周快走2.5小时
  16. 为了摸鱼,我开发了一个工具网站
  17. 算法笔记(18)数据升维及Python代码实现
  18. 微信小程序绘制自定义海报,可带二维码,头像,文字等
  19. superset汉化
  20. 如何度过人生艰难:魔都28岁硬核知识型美少女自救指南

热门文章

  1. prng伪随机数生成器_Java伪随机数生成器(PRNG)中的弱点
  2. 第1015期机器学习日报(2017-06-29)
  3. IDEA运行项目时停不下来
  4. 《你的降落伞是什么颜色》-- 读书笔记
  5. Windows批处理学习(一)——MS-DOS命令
  6. 一行python代码能实现什么丧心病狂的功能_一行Python 能实现什么丧心病狂的功能...
  7. Dell R730 xd “CPU 2 M23 VPP PG voltage is outside of range“故障
  8. 该微信用户未开启“公众号安全助手”的消息接收功能,请先开启后再绑定的解决办法
  9. 碰撞的小球(100分)
  10. 怎么以最新汇率牌价计算XX美元相当于多少人民币