一文读懂WPF系列之MVVM

WPF MVVM

什么是MVVM

翻译全称就是 model-view-viewmodel 3部分内容

  1. 以wpf的概念角度来解释就是 数据库数据源模型----xmal UI视图----DataContext​​ Viewmodel使用模型承载方式

  2. 以技术点的角度来解释就是通过 UI的依赖属性 - binding-ViewModel 数据之间 双向绑定

    UI控件内容变动可以作用于viewmodel,viewmodel模型内容变动也可以作用于UI控件内容显示

WPF为何使用MVVM机制

  1. 职责分离
    View:仅负责 UI 呈现,通过 XAML 绑定依赖属性。
    ViewModel:处理业务逻辑,通过 INotifyPropertyChanged 驱动数据流。
    Model:封装数据结构和业务规则。
  2. 可测试性与维护性
    ViewModel 独立于 UI,便于单元测试。
    样式与逻辑解耦,支持设计师与开发者并行工作

WPFMVVM 的实现手段

在 WPF 中,​​依赖属性​​、​​数据绑定​​和 INotifyPropertyChanged 是支撑 MVVM(Model-View-ViewModel)设计模式的三大核心

  1. 依赖属性与 View 的绑定
    自定义控件:通过依赖属性定义控件行为(如 NumericBox.Value),并绑定到 ViewModel 属性。
    数据模板:在控件模板中使用 TemplateBinding 关联依赖属性与模板元素。
  2. INotifyPropertyChanged 与 ViewModel 的绑定
    数据驱动 UI:ViewModel 的 CLR 属性通过 INotifyPropertyChanged 实现双向绑定,例如用户输入实时同步到数据源。
    工具辅助:使用 Fody 库的 [ImplementPropertyChanged] 特性自动生成属性变更代码,减少样板代码。
  3. 数据绑定引擎的协作
    绑定模式:
    单向绑定(OneWay):依赖属性监听 ViewModel 属性变化。
    双向绑定(TwoWay):依赖属性与 ViewModel 属性互相更新,例如 TextBox.Text 与 ViewModel.InputText。
    验证与转换:通过 IValueConverter 和 ValidationRule 实现数据格式转换与输入验证

INotifyPropertyChanged

​数据绑定的源端通知​​

​​ViewModel 的职责​​:ViewModel 中的 CLR 属性需实现 INotifyPropertyChanged,以便在值变更时通过 PropertyChanged 事件通知 UI 更新

javascript 复制代码
public class ViewModel : INotifyPropertyChanged {
    private string _userName;
    public string UserName {
        get => _userName;
        set { _userName = value; OnPropertyChanged(nameof(UserName)); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) 
        => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

<TextBox Text="{Binding UserName, Mode=TwoWay}" />

原理 PropertyChanged事件

  1. INotifyPropertyChanged 是一个接口,定义了一个 PropertyChanged 事件
  2. 当 ViewModel 中的属性值发生变化时,触发 PropertyChanged 事件,并传递属性名称。
  3. WPF 的绑定引擎会监听此事件,并根据属性名称更新对应的 UI 元素

双向绑定的完整条件

  1. 目标属性是依赖属性(如 TextBox.Text)。
  2. 源属性实现 INotifyPropertyChanged(ViewModel 属性)。
  3. 显式设置 Mode=TwoWay(除非依赖目标属性默认支持双向)。
  4. 更新触发时机:通过 UpdateSourceTrigger 控制同步时机(如 PropertyChanged 或 LostFocus)

常见疑惑问题

  1. 如果没有用到INotifyPropertyChanged,即使binding 设置了 twoway 也无法viewmodel变更后 作用UI显示
  2. 绑定不更新
    可能原因:
    未正确调用 OnPropertyChanged。
    属性名称拼写错误(使用 nameof 避免)。
    未启用 Mode=TwoWay(如需要从 View 更新到 ViewModel)
  3. 目前DataContext是通过=this的写法 来表现数据源的,无法使用mvvm 所以为什么推荐使用 viewmodel的写法来使用,DataContext = this 的适用场景:仅适用于原型验证或极小规模工具,不推荐生产环境使用
  4. 在 WPF 中,若绑定模式设置为 OneWay,且 ViewModel 实现了 INotifyPropertyChanged 接口,数据源的变更会触发 UI 更新,但 UI 的修改不会反向同步到数据源
相关推荐
听麟11 小时前
HarmonyOS 6.0+ APP AR文旅导览系统开发实战:空间定位与文物交互落地
人工智能·深度学习·华为·ar·wpf·harmonyos
聆风吟º1 天前
CANN hccl 深度解析:异构计算集群通信库的跨节点通信与资源管控实现逻辑
人工智能·wpf·transformer·cann
无心水1 天前
分布式定时任务与SELECT FOR UPDATE:从致命陷阱到优雅解决方案(实战案例+架构演进)
服务器·人工智能·分布式·后端·spring·架构·wpf
LZL_SQ1 天前
HCCL测试框架中AllReduce边界条件测试设计深度剖析
wpf·cann
User_芊芊君子2 天前
【分布式训练】CANN SHMEM跨设备内存通信库:构建高效多机多卡训练的关键组件
分布式·深度学习·神经网络·wpf
就是有点傻3 天前
WPF按钮走马灯效果
wpf
zuozewei3 天前
虚拟电厂聚合商平台安全技术体系深度解读
安全·wpf
极客智造3 天前
WPF 自定义控件:AutoGrid 实现灵活自动布局的网格控件
wpf
极客智造3 天前
WPF Grid 布局高效扩展:GridHelpers 附加属性工具类全解析
wpf
张人玉3 天前
WPF 多语言实现完整笔记(.NET 4.7.2)
笔记·.net·wpf·多语言实现·多语言适配