ContentControl not updating

本文关键字:updating not ContentControl | 更新日期: 2023-09-27 18:03:21

我试图有一个绑定到视图的主窗口。我在代码中更改了该视图,并期望它在主窗口中更新,但这并没有发生。

我的XAML

中有这段代码
<Grid>
    <ContentControl Content="{Binding Source={StaticResource ViewModelLocator}, Path=MainWindowViewModel.CurrentControl}" />
</Grid>

然后通过以下代码更改控件

public class MainWindowViewModel : ReactiveObject
{
    private UserControl _CurrentControl = null;
    public UserControl CurrentControl
    {
        get
        {
            if (_CurrentControl == null)
            {
                _CurrentControl = new HomePage();
            }
            return _CurrentControl;
        }
        set
        {
            this.RaiseAndSetIfChanged(x => x.CurrentControl, value);
        }
    }
}

正如你所看到的,我正在使用ReactiveUI库。

ContentControl在该视图中使用错误的东西,还是我只是没有正确绑定和更新?

ContentControl not updating

实际上有一个更好的方法做到这一点,使用ViewModelViewHost:

<Grid DataContext="{Binding ViewModel, ElementName=TheUserControl}">
    <ViewModelViewHost ViewModel="{Binding CurrentControlViewModel}" />
</Grid>
现在,你的类看起来像:
public class MainWindowViewModel : ReactiveObject
{
    private ReactiveObject _CurrentControlViewModel = new HomePageViewModel();
    public ReactiveObject CurrentControlViewModel {
        get { return _CurrentControl; }
        set { this.RaiseAndSetIfChanged(x => x.CurrentControlViewModel, value); }
    }
}

在你的应用启动的某个地方,你应该写:

RxApp.Register(typeof(IViewFor<HomePageViewModel>), typeof(HomePage));

ViewModelViewHost是什么?

ViewModelViewHost将通过绑定提供一个ViewModel对象,并且查找一个适合它的视图,使用服务位置。Register调用是你将view和ViewModels关联起来的方法。

为什么你叫你的类MainWindowViewModel?当你想做mvvm时,你不应该在你的VM中有UserControl类型的属性。

通常的MVVM方式如下:

  • 带有INotifyPropertyChanged的视图模型
public class MyViewmodel
{
    public IWorkspace MyContent {get;set;}
}
  • 绑定到VM的xaml内容控件
<ContentControl Content="{Binding MyContent}"/>
  • datatemplate ->让wpf知道如何渲染你的IWorkspace
<DataTemplate DataType="{x:Type local:MyIWorkSpaceImplementationType}" >
   <view:MyWorkspaceView />
</DataTemplate>

我认为你这里有几个混淆的概念,它们相互妨碍。

首先,你实际上没有使用任何的reactiveUI代码,它永远不会被调用。由于您的get访问器实现了延迟实例化模式,因此这意味着set访问器将被忽略。这意味着视图永远不会通知属性更改,因此您永远不会获得更新。

我建议使用更像

这样的字符
private UserControl _currentControl;
public MainWindowVirwModel()
{
  CurrentControl = new HomePage();
}
public UserControl CurrentControl
{
  get { return _curentControl;}
  set { this.RaiseAndSetIfChanged(...); }
}

此外,这仍然混合了视图组件,例如首页,在你的ViewModel层中,这将使单元测试更加困难。