一文读懂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 的修改不会反向同步到数据源
相关推荐
玖笙&3 天前
✨WPF编程基础【2.1】布局原则
c++·wpf·visual studio
玖笙&3 天前
✨WPF编程基础【2.2】:布局面板实战
c++·wpf·visual studio
SEO-狼术3 天前
.NET WPF 数据编辑器集合提供列表框控件
.net·wpf
FuckPatience7 天前
WPF 具有跨线程功能的UI元素
wpf
诗仙&李白7 天前
HEFrame.WpfUI :一个现代化的 开源 WPF UI库
ui·开源·wpf
He BianGu7 天前
【笔记】在WPF中Binding里的详细功能介绍
笔记·wpf
He BianGu7 天前
【笔记】在WPF中 BulletDecorator 的功能、使用方式并对比 HeaderedContentControl 与常见 Panel 布局的区别
笔记·wpf
123梦野8 天前
WPF——效果和可视化对象
wpf
He BianGu8 天前
【笔记】在WPF中Decorator是什么以及何时优先考虑 Decorator 派生类
笔记·wpf
时光追逐者9 天前
一款专门为 WPF 打造的开源 Office 风格用户界面控件库
ui·开源·c#·.net·wpf