MVVM在WPF中需严格遵循职责分离、INotifyPropertyChanged通知、ICommand行为绑定及松耦合约束;缺一不可,否则退化为紧耦合代码。
WPF 中实现 MVVM 不是靠某个“魔法开关”,而是靠明确分离职责 + 正确绑定机制 + 一套约定俗成的支撑结构。没引入 INotifyPropertyChanged 或没走 Binding 路径,就不是真正可用的 MVVM。
INotifyPropertyChanged 才能触发 UI 自动更新ViewModel 层任何需要响应式更新 View 的属性,都得手动通知变更。WPF 的 Binding 默认只监听这个接口,不实现它,改了属性值 UI 也纹丝不动。
常见错误:只写属性 getter/setter,却忘了 raise PropertyChanged;或在后台线程里直接调用 OnPropertyChanged 导致跨线程异常。
nameof(MyProperty) 替代字符串字面量,避免重命名后绑定失效FullName 依赖 FirstName 和 LastName),修改任一依赖项时都要主动触发 FullName 的通知Task.Run)中更新属性前,确保用 Dispatcher.Invoke 或 await Dispatcher.BeginInvoke 回到 UI 线程ICommand 是连接 View 和 ViewModel 行为的核心桥梁按钮点击、菜单执行等交互逻辑不该写在 Code-Behind,而应由 ViewModel 提供 ICommand 实例(常用 RelayCommand 或 DelegateCommand 自定义实现),View 通过 Command 属性绑定触发。
典型陷阱:命令执行方法里抛异常未捕获,导致 UI 冻结或静默失

CanExecute 没关联状态变化,按钮一直不可点或该禁用时仍可点。
CanExecuteChanged 必须被正确触发——比如用 CommandManager.RequerySuggested 订阅全局建议,或在相关属性变更时手动调用 OnCanExecuteChanged()
Execute 中直接操作 TextBox.Text 这类 UI 元素,所有数据应流经绑定的属性Button.CommandParameter),确保 Execute(object parameter) 方法能安全处理 null 或类型不匹配View 的 DataContext 必须设为 ViewModel 实例(通常在 XAML 中用 DataContext="{Binding Source={StaticResource MyVm}}" 或代码中赋值),且所有 Binding Path=xxx 都要对应 ViewModel 上的 public 属性或属性链(如 Path=User.Name)。
常见失败现象:Output 窗口刷出 “BindingExpression path error”,说明路径不存在、访问级别不对(如 internal)、或 DataContext 根本没设对。
Loaded 事件去 new ViewModel——这会破坏松耦合,也妨碍设计时数据上下文(DesignTime DataContext)生效d:DataContext="{d:DesignInstance local:MyViewModel}" 让 XAML 编辑器显示模拟数据,同时不影响运行时行为ObservableCollection,普通 List 增删元素不会通知 UIMVVM 的复杂性不在语法,而在约束力——一旦漏掉 INotifyPropertyChanged 的一次通知,或让 View 直接调用 ViewModel 的 void 方法而不走 ICommand,整个模式就退化成披着 MVVM 外衣的紧耦合代码。真正难的是持续守住这条边界。