6

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

我的 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该视图中使用错误的东西还是我没有正确绑定和更新?

4

3 回答 3

10

实际上有一个更好的方法可以做到这一点,使用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将获取您通过 Bindings 提供的 ViewModel 对象,并使用 Service Location查找适合它的 View。Register 调用是您可以将 View 与 ViewModel 相关联的方式。

于 2013-03-12T21:07:30.293 回答
5

为什么你叫你的班级 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>
于 2013-03-12T07:30:54.210 回答
3

我认为您在这里有几个混乱的概念,它们相互干扰。

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

我建议使用更像

private UserControl _currentControl;

public MainWindowVirwModel()
{
  CurrentControl = new HomePage();
}

public UserControl CurrentControl
{
  get { return _curentControl;}
  set { this.RaiseAndSetIfChanged(...); }
}

此外,这仍然会在 ViewModel 层中混淆 View 组件,即 HomePage,这将使单元测试变得更加困难。

于 2013-03-12T08:25:26.280 回答