2017-06-12 129 views
0

我是初學者,在設置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」?它是一個視圖模型還是一個控件? –

回答

0

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爲管道(沒有必要重新發明輪子)

0

確切....做任何改變伊戈爾告訴你。 有沿,

更改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

0

後與相似的目的也幫助我得到的東西:

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

基本上我想要實現的是一個單一窗口中管理內容區域和任何內部消除框架和更精確管理「交易」,即在用戶交互時從一個屏幕切換到另一個屏幕。

感謝所有的評論,事情變得更加清晰。