2013-10-29 109 views
34

我有多個視圖的WPF應用程序。我想從圖1 toswitch查看2和從那裏我可以切換到多個視圖。所以我想在視圖1上的一個按鈕將view2加載到同一個窗口中。WPF MVVM導航意見

我想這些東西,但不能讓它的工作。

從第一個環節的問題是,我不明白的viewmodellocator代碼。他們稱之爲CreateMain();的功能,但其中該限定,以及如何切換到其它視圖從一個視圖內。

+1

@AndrasSebö,在這個場合,我不同意你的看法。雖然我接受這不是一個很好的問題,但我已經看到了更糟糕的情況,而且我相信用戶之後很清楚。 – Sheridan

+2

那麼問題是:我如何從視圖內切換視圖。 – user2499088

+1

您是否找到解決此問題的好方法? – User1551892

回答

6

當我第一次開始使用MVVM時,我也在努力應對不同的MVVM框架,特別是導航部分。因此,我使用Rachel Lim創建的這個小教程。這很好,很好解釋。

看一看它下面的鏈接:

希望它可以幫助你:)

+1

謝謝,但這不是我的意思。我將這個例子用於另一個應用程序,但對於這個應用程序,我沒有sidemenu。所以我在view1上有一個按鈕,當我點擊那個按鈕時它必須切換到view2 – user2499088

87

首先,你不需要任何的工具包/框架實現MVVM。它可以像這樣簡單...讓我們假設我們有一個MainViewModel,PersonViewModel和一個CompanyViewModel,每個都有自己的相關視圖,並且每個都擴展了abstract基類BaseViewModel

BaseViewModel中,我們可以添加公共屬性和/或ICommand實例並實現INotifyPropertyChanged接口。因爲它們都延長BaseViewModel類,我們可以在這可設置爲任何我們認爲模型的MainViewModel類此屬性:上正確

public BaseViewModel ViewModel { get; set; } 

當然,你會實現INotifyPropertyChanged接口您屬性不像這個快速的例子。現在,在App.xaml,我們宣佈了一些簡單的DataTemplate s到的意見與視圖模型連接:

<DataTemplate DataType="{x:Type ViewModels:MainViewModel}"> 
    <Views:MainView /> 
</DataTemplate> 
<DataTemplate DataType="{x:Type ViewModels:PersonViewModel}"> 
    <Views:PersonView /> 
</DataTemplate> 
<DataTemplate DataType="{x:Type ViewModels:CompanyViewModel}"> 
    <Views:CompanyView /> 
</DataTemplate> 

現在,無論我們用BaseViewModel實例之一,我們的應用程序,這些DataTemplate旨意告訴框架顯示相反的看法。我們可以這樣顯示出來:

<ContentControl Content="{Binding ViewModel}" /> 

因此,所有我們現在需要做的切換到一個新的觀點是從MainViewModel類設置ViewModel屬性:

ViewModel = new PersonViewModel(); 

最後,我們怎麼樣從其他視圖改變觀點?那麼有幾種可能的方法可以做到這一點,但最簡單的方法是將子視圖中的Binding直接添加到MainViewModel中的ICommand。我用的是RelayComand的定製版本,但你可以使用任何你喜歡的類型,我猜你會得到的圖片:

public ICommand DisplayPersonView 
{ 
    get { return new ActionCommand(action => ViewModel = new PersonViewModel(), 
     canExecute => !IsViewModelOfType<Person>()); } 
} 

在子視圖XAML:

<Button Command="{Binding DataContext.DisplayPersonView, RelativeSource= 
    {RelativeSource AncestorType={x:Type MainView}}, Mode=OneWay}" /> 

而已!請享用。

+0

我認爲這會起作用。但是當我做視圖模型=新...我得到的錯誤「視圖模型是一個屬性,但作爲一種」 – user2499088

+1

你的'ViewModel'屬性的類型設置爲'BaseViewModel',做你的視圖模型的所有擴展那個班? – Sheridan

+1

嗯,我使用MVVM光,其全部設爲ViewModelBase,但所有的ViewModels繼承了該類,並設有ViewModelBase – user2499088

1

也許this鏈接將幫助你。只需將NavigateTo屬性設置爲您需要在窗口上顯示的視圖。

正如你可以這樣做

<Window x:Class="MainWindowView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
           xmlns:meffed="http:\\www.codeplex.com\MEFedMVVM" 
           meffed:ViewModelLocator.NonSharedViewModel="YourViewModel" 
           WindowStartupLocation="CenterScreen"> 

    <Button meffed:NavigationExtensions.NavigateTo="firstview" 
        meffed:NavigationExtensions.NavigationHost="{Binding ElementName=_viewContainer}" 
        meffed:NavigationExtensions.NavigateOnceLoaded="False" 
        Visibility="Visible" /> 

    <ContentControl x:Name="_viewContainer" Margin="0,0,0,10" /> 
<Window> 

一個例子吧類文件將

public partial class MainWindowView : Window 
{ 
    public MainWindowView() 
    {   
       InitializeComponent(); 
    } 

     public ContentControl ViewContainer { get { return _viewContainer; } } 

    } 

然後,你可以定義每個視圖UserControl,然後用我上面給的鏈接綁定按鈕的meffed:NavigationExtensions.NavigateTo="secondView"。要使Window的目標ContentControl僅使用RelativeSource綁定。對於e.g

meffed:NavigationExtensions.NavigationHost="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=ViewContainer}"

在每個觀點只是看到你背後註解類定義的代碼與[NavigationView("firstview")]等。

第一次很複雜,但一旦理解了這個想法,它會變得非常簡單。

0
<ContentControl x:Name="K.I.S.S" Content="{Binding ViewModel, Converter={StaticResource ViewLocator}}"/>