WPF与MVVM:如何通过嵌套UserControl向ViewModel传递对象
解决嵌套UserControl依赖属性传递为null的问题
问题根源
你的SubSubUserControl在OnInitialized中初始化ViewModel时,依赖属性Object的绑定值还未完成赋值。WPF的控件初始化流程里,OnInitialized会先于绑定值的更新执行,所以此时Object还是默认的null。
解决方案
方案1:监听依赖属性变化,动态更新ViewModel
修改SubSubUserControl的依赖属性注册逻辑,添加属性变更回调,当Object值真正传入时再初始化ViewModel:
public static readonly DependencyProperty ObjectProperty = DependencyProperty.Register( nameof(Object), typeof(Object), typeof(SubSubUserControl), new PropertyMetadata(null, OnObjectPropertyChanged)); public Object Object { get => (Object)GetValue(ObjectProperty); set => SetValue(ObjectProperty, value); } private static void OnObjectPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var control = (SubSubUserControl)d; // 当属性值更新时,初始化ViewModel control.DataContext = new SubSubUserControlViewModel(e.NewValue as Object); } protected override void OnInitialized(EventArgs e) { InitializeComponent(); // 不再在此处初始化ViewModel,交给属性变更回调处理 base.OnInitialized(e); }
方案2:推迟ViewModel初始化到Loaded事件
Loaded事件会在控件完全加载、绑定值已更新后触发,此时Object属性已获得正确值:
protected override void OnInitialized(EventArgs e) { InitializeComponent(); Loaded += SubSubUserControl_Loaded; base.OnInitialized(e); } private void SubSubUserControl_Loaded(object sender, RoutedEventArgs e) { DataContext = new SubSubUserControlViewModel(Object); Loaded -= SubSubUserControl_Loaded; // 避免重复触发 }
方案3:基于MVVM的间接传递(更推荐)
既然SubUserControl已经将DataContext设置为SubUserControlViewModel,可以在该ViewModel中暴露Object属性,让SubSubUserControl直接绑定父ViewModel的属性,无需依赖控件的依赖属性:
- 修改
SubUserControlViewModel,添加Object属性:
public class SubUserControlViewModel { public Object Object { get; } public SubUserControlViewModel(Object obj) { Object = obj; } }
- 修改
SubUserControl的XAML,让SubSubUserControl绑定父级ViewModel的Object:
<local:SubSubUserControl Object="{Binding Object}" />
SubSubUserControl的后台代码可保持原逻辑,此时绑定的是ViewModel的属性,值会在DataContext设置后正确传递。
额外提示
MainWindow中的Object是普通CLR属性,若后续需要动态更新,建议实现INotifyPropertyChanged接口,否则绑定无法响应属性值变化。- 依赖属性命名尽量避免和系统类型
Object重名,比如改为MyObject,减少代码混淆。
内容的提问来源于stack exchange,提问作者Rowandish
相关产品推荐
相关产品推荐

