正确分离视图和视图模型

问题描述:

我是初学者,在设置WPF项目和跟随MVVM模式时遇到问题;我不明白如何将视图链接到以下组织的视图模型:正确分离视图和视图模型

我已经在名为“Company.App.UI”的项目的根目录下设置了3个文件夹:Model,View和ViewModel。 App.xaml和MainWindow.xaml位于项目的根目录下。

这个开始,我想控制在主窗口的客户区中显示的内容: - 具有文件夹“查看”用户控件作为在渲染视图,例如“LoginView.xaml” - 具有相应该文件夹 '视图模型',例如在浏览模式 'LoginView.xaml.cs'

那么我所做的MainWindow.xaml是:

<Window x:Class="Company.App.UI.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:viewmodel="clr-namespace:Company.App.UI.ViewModel" 
     xmlns:view="clr-namespace:Company.App.UI.View" <!-- does not work, not a namespace --> 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type viewmodel:LoginViewModel}"> 
      <view:LoginView/> <!-- does not work --> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <StackPanel Grid.Row="0" Orientation="Horizontal"> 
      <ContentControl Content="{Binding ClientArea}"/> 
     </StackPanel> 
    </Grid>   
</Window> 

而且在MainWindow.xaml.cs:

using System.Windows; 
using System.Windows.Controls; 
using Company.App.UI.ViewModel; 

namespace Company.App.UI 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
    private UserControl _ClientArea = null; 

    public UserControl ClientArea 
    { 
     get { return _ClientArea; } 
     set { _ClientArea = value; } 
    } 

    public MainWindow() 
    { 
     if (_ClientArea == null) { ClientArea = new LoginViewModel(); } 
     InitializeComponent(); 
    } 
    } 
} 

LoginView是一个带有一个标签的简单用户控件,只是为了看看它是什么。 如果我把我的LoginView.xaml放在项目的根目录下,MainWindow.xaml旁边,它可以工作... 我在做什么错误/缺失? 我不想使用任何框架(PRISM等)来实现它的工作。 我的道歉如果我的文章是重复的,但我也没有找到它,而搜索。 谢谢,

更新

我用VS2013 0更新/补丁/等 一切都在同一个项目。

的错误输出是:

  1. 类型或命名空间名称“查看”中不 命名空间“Company.App.UI”存在(是否缺少程序集引用?)
  2. 的命名空间 “clr-namespace:Company.App.UI.View”中不存在名称“LoginView”。
  3. 找不到类型'view:LoginView'。验证您是否缺少程序集引用,并且所有引用的程序集都已构建。

LoginView.xaml:

<UserControl x:Class="Company.App.UI.ViewModel.LoginViewModel" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid> 
     <Label>User control login</Label> 
    </Grid> 
</UserControl> 

LoginViewModel.cs:

using System.Windows.Controls; 

namespace Company.App.UI.ViewModel 
{ 
    public partial class LoginViewModel : UserControl 
    { 
    public LoginViewModel() 
    { 

    } 
    } 
} 
+0

文件夹结构不相关。您必须在代码文件中使用适当的名称空间声明,例如'namespace Company.App.UI.View {...}' – Clemens

+1

*“它的工作原理”* - 什么不起作用?你想[改进](https://codereview.stackexchange.com/)工作代码? – Sinatr

+0

'ClientArea'被声明为'UserControl'(非常糟糕的想法)。然后你为它分配一个叫做“LoginViewModel”的东西。什么是“LoginViewModel”?它是一个视图模型还是一个控件? –

LoginView。XAML更改此:

x:Class="Company.App.UI.ViewModel.LoginViewModel" 

这个

x:Class="Company.App.UI.ViewModel.LoginView" 

,因为这不是一个控制一个ViewModel

而且,这是LoginView.xaml.cs应该怎么样子(没有看到你的实现):

using System.Windows.Controls; 

namespace Company.App.UI.View 
{ 
    /// <summary> 
    /// Interaction logic for LoginView.xaml 
    /// </summary> 
    public partial class LoginView : UserControl 
    { 
     public LoginView() 
     { 
      InitializeComponent(); 
     } 
    } 
} 

当你会得到它的挂(mvvm)我会建议使用mvvm light toolkit为管道(没有必要重新发明*)

确切....做任何改变伊戈尔告诉你。 有沿,

更改MainWindow.xaml.cs

if (_ClientArea == null) { ClientArea = new LoginViewModel(); } 

if (_ClientArea == null) { ClientArea = new LoginView(); } 

而且按照我的理解,你只是想显示来自用户控制一个标签,可以主窗口,想学习MVVM的概念。因此,这里是您例如交代这可以帮助你

<Grid> 
     <!--connect to viewmodel--> 
     <Grid.DataContext> 
     <viewmodel:LoginViewModel></viewmodel:LoginViewModel> 
     </Grid.DataContext> 

     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto"/> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 

     <!--import user control--> 
     <view:LoginView Grid.Row="0"></view:LoginView> 

     <StackPanel Grid.Row="1" Orientation="Horizontal"> 
      <ContentControl Content="{Binding ClientArea}"/> 
     </StackPanel> 

    </Grid> 

注 - 尽量保持零代码的任何代码后面。这就是MVVM的主要目的。它应该只是有

  • 型号...(类里面应该有纯粹只是根据企业的性质文件)
  • 查看......(用户控件,XAML,窗口文件,该文件应包含只是
    XAML代码零代码背后)
  • 模型变换...(类文件,其应该包含视图和模型之间纯粹连接 ,其不应当包含 视图的任何物体或model.It连接通过结合)

我也不知道你创建'ClientArea'的目的是什么......你是否在某个地方定义了它的内容?
让我知道你是否需要任何帮助...我在MVVM上有一些示例演示项目。

+0

我从上面的所有评论中看到了我的错误:错误是混淆了xaml代码隐藏(.xaml.cs)和另一个.cs的viewmodel。 – Minuqx

+0

我很高兴它帮助!! 1 – Lina

后与相似的目的也帮助我得到的东西:

Binding a ContentControl to UserControl, and reuse same instance

用在此处的优秀主题:How to preserve the full state of the View when navigating between Views in an MVVM application?

另一个好点开始,我发现后,我发表我的问题(...):https://msdn.microsoft.com/en-us/library/gg405484(v=pandp.40).aspx

基本上我想要实现的是一个单一窗口中管理内容区域和任何内部消除框架和更精确管理“交易”,即在用户交互时从一个屏幕切换到另一个屏幕。

感谢所有的评论,事情变得更加清晰。