INotifyPropertyChanged:属性变化通知机制
UI 仅在被通知属性变更时刷新。通过实现 INotifyPropertyChanged 接口并在属性 set 中调用 OnPropertyChanged(),可触发绑定控件的更新。
常见问题
- 仅修改字段(如
_username = value)不会触发通知,需通过属性赋值。 - 手动书写属性名易出错,建议使用
[CallerMemberName]自动捕获属性名。
ObservableCollection:集合动态更新原理
普通 List<T> 不提供集合变更通知,而 ObservableCollection<T> 会在 Add/Remove/Clear 时自动通知绑定控件(如 ListView)。
常见问题
- 替换为
List<T>后,集合变更不会反映到 UI。 - 集合内对象属性变更需依赖对象自身的
INotifyPropertyChanged实现。
ICommand/RelayCommand:MVVM 行为逻辑解耦
MVVM 模式下,ICommand 将用户操作(如按钮点击)绑定到 ViewModel 逻辑,避免在 View 层编写业务代码。
优势
- 便于单元测试(无需依赖 UI 层)。
- 逻辑集中管理,维护性更高。
改进点
- 复杂场景中,
CanExecute需结合CommandManager.RequerySuggested实现实时状态更新。
DataContext:绑定路径解析起点
绑定路径从当前控件的 DataContext 开始解析。若中间控件修改了 DataContext,子控件绑定路径可能失效。
示例
XML
{Binding MainViewModel.Users} <!-- 从窗口级 DataContext 的 MainViewModel 属性开始查找 -->
ContextMenu 绑定问题与 BindingProxy 方案
ContextMenu 脱离主视觉树,默认无法继承父级 DataContext,需通过 BindingProxy 显式传递。
解决方案
-
在资源中定义
BindingProxy:XML<Window.Resources> <local:BindingProxy x:Key="MainViewModelProxy" Data="{Binding MainViewModel}"/> </Window.Resources> -
通过静态资源引用:
XML<MenuItem Command="{Binding Source={StaticResource MainViewModelProxy}, Path=Data.DeleteUserCommand}"/>
核心逻辑串联
- 数据源 :
DataContext定义绑定起点。 - 属性更新 :
INotifyPropertyChanged通知 UI。 - 集合更新 :
ObservableCollection同步增删操作。 - 用户操作 :
ICommand将行为路由至 ViewModel。 - 特殊控件 :
ContextMenu通过BindingProxy绑定上下文。