WPF MVVM模式下如何通过Command为UserControl设置DataContext
问题根源
你当前的问题出在HomeView.xaml里手动硬编码了DataContext:
<UserControl.DataContext> <viewModel:HomeViewModel/> </UserControl.DataContext>
这段代码会在HomeView初始化时创建一个全新的独立HomeViewModel实例,和你在MainViewModel里提前初始化、调用过Initialize方法传参的HomeVM完全是两个对象,自然你修改MainViewModel里的实例,HomeView绑定的自己生成的空实例所有参数都是null。
解决方案
第一步:删除UserControl里手动写的DataContext声明
直接删掉HomeView、UserView等所有通过DataTemplate加载的UserControl里的<UserControl.DataContext>整块代码即可。
你已经用了ViewModel-first的绑定逻辑:ContentControl的Content绑定的是MainViewModel里已经初始化完成的ViewModel实例,匹配到App.xaml里的DataTemplate生成对应的View时,WPF会自动把View的DataContext设置为你绑定的ViewModel实例,完全不需要手动赋值。
可选优化:保留设计时智能提示
如果你需要在写XAML时保留ViewModel的智能提示,可以在UserControl的头部加设计时专属的DataContext声明,不会影响运行时的绑定:
<UserControl <!-- 其他命名空间省略 --> d:DataContext="{d:DesignInstance viewModel:HomeViewModel, IsDesignTimeCreatable=True}" >
扩展:访问UserControl的DataContext
你不需要绕路从View层拿DataContext,直接用MainViewModel里持有的HomeVM、UserVM实例即可,它们和View绑定的是同一个对象,修改这些实例的属性会自动同步到界面。
如果确实需要在MainWindow的后台代码里取当前显示的ViewModel,可以直接拿ContentControl的Content属性强转:
// 取当前显示的ViewModel var currentVm = CC_View.Content as ObservableObject; // 强转为具体类型即可操作 if (currentVm is HomeViewModel homeVm) { // 你的操作逻辑 }
内容的提问来源于stack exchange,提问作者Jongkwan Park

