【问题标题】:How to change whole views in MVVM without “grandparent” DataContext?如何在没有“祖父母” DataContext 的情况下更改 MVVM 中的整个视图?
【发布时间】:2015-03-02 04:49:57
【问题描述】:

我在 Internet 上看到的所有示例都有两个区域 - 一个区域用于更改视图的按钮,另一个区域用于应由该按钮更改的视图。所以它一直有效,直到您尝试访问位于“祖父”数据上下文中的命令。但是,我想将整个视图更改为另一个视图,而不需要划分区域或任何侧边栏并将数据从 View1 发送到 View2,然后更新 View1。

我正在尝试更改 MVVM 应用程序中的视图。例如,我有“ApplicationView”(一个包含 Views1(UserControl1) 和 View2(UserControl2) 的 DataTemplates 的主机)。这些用户控件有自己的数据上下文。 ApplicationView 的 xml 是:

<Window ……..>    
<Window.Resources>
    <DataTemplate DataType="{x:Type localViewModel:VMMain}">
        <localView:MainView/>            
    </DataTemplate>
    <DataTemplate DataType="{x:Type localViewModel:VMEditStudent}">
        <localView:EditStudentView/>
    </DataTemplate>
</Window.Resources>    
<Grid>
    <ContentControl Content="{Binding CurrentPageViewModel}"/>
</Grid>

View 1(UserControl1) 有自己的 DataContext:

View 2(UserControl2) 也有自己的 DataContext:

我想要的是在 DataGrid 中选择一个项目(Adam),单击“编辑”按钮,然后 View1 应该被 View 2 替换为来自数据网格的填充数据。据我了解,我应该通过处理“编辑”按钮的命令来更改 View1,然后应该显示 View 2,然后我更改数据,然后应该更新 View1。怎么做?

我们将不胜感激一些带有代码的示例!谢谢。

【问题讨论】:

  • 你看过 Prism 框架和它的 RegionManager 吗?
  • @Tseng,是的,我看过这个例子,这些例子很有趣。
  • RegionManager 独立于侧边栏工作。您在 XAML 中定义区域并命名它们,然后从代码中导航它们。参考应用程序显示了最佳实践,并且您建议的此类行为不被视为桌面上的最佳实践,并且更类似于移动应用程序的可用性。 RegionManager 仍然应该涵盖您的情况
  • @Tseng,谢谢。但是,我找不到没有侧边栏导航的好例子。请您分享一些示例或链接以查看示例。

标签: c# wpf mvvm view navigation


【解决方案1】:

您的示例与您提到的典型示例类似,只是您的视图按钮位于其中一个视图中。解决方案只是将Button.Command 属性数据绑定到父视图模型中的命令。这可以通过一个简单的RelativeSource Binding 来完成:

UserControl1XAML:

<Button Content="Edit" Command="{Binding DataContext.EditCommand, 
    RelativeSource={RelativeSource AncestorType={x:Type YourPrefix:YourParentView}}}" />

在父视图模型编辑命令中,你需要这样的东西:

CurrentPageViewModel = new ViewModelForUserControl2(UserControl1.SelectedDataObject);

当然,您还必须将所选项目公开为来自UserControl1DependencyProperty,以便您可以将其传递给UserControl2

【讨论】:

  • 我是否正确理解 View1 应该包含 View2 的数据模板?但是我的 view1 不能包含用于更改视图的 ContentControl,因为 View1 具有 Datagrid。 CurrentPageViewModel 属性是否应该在 ApplicationViewModel 中是静态的,然后创建对象(CurrentView.ChangeViewCommand = this.ChangeViewCommand 从 ViewViewmodel1 设置 ViewViewModel2?谢谢。
  • 我说的对吗?
  • 我是否理解正确“在父视图模型编辑命令中,您需要这样的东西:CurrentPageViewModel...”,CurrentPageViewModel 必须在 View1ViewModel 中?但是我在 ApplicationViewModel 中有一个属性“CurrentPageViewModel”。我在 View1ViewModel 中没有 CurrentPageViewModel 属性。非常感谢。
  • 我是否正确理解 View1 应该包含 View2 的数据模板?...我不记得说过类似的话。 CurrentPageViewModel 属性在 ApplicationViewModel 中应该是静态的吗?...不。 我说的对吗?...您忘记了 DataTemplate. 中的 Binding PathCurrentPageViewModel 必须在 View1ViewModel 中?...不,它应该在主(父)视图模型中...这就是我们使用 RelativeSource Binding 到达那里的原因。
  • 恕我直言,我不是来教你 WPF 的。因此,这将是我最后的评论……尽你所能。您有一个窗口,其对象设置为DataContext...该对象应该是您的主视图模型,并具有您的CurrentPageViewModel 属性和您的ICommand 更改该属性值。您可以使用来自任何子控件的RelativeSource Binding 来访问该ICommand。而已! ICommand 是从任何一个视图触发的,它会更改父视图模型属性并更改视图。这里的所有都是它的。结束!
猜你喜欢
  • 2015-11-25
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多