MVVM Mehrere Views, 1 ViewModel (Portable Class Library)
-
Hallo,
ich versuche seit Neuestem das MVVM-Pattern für meine Windows 8 App / Windows 8 Phone App zu verwenden.
Leider bin ich auf das Problem gestoßen, dass ich bei Klick auf einem Button nicht die View in den ContentController laden kann. Meine Struktur sieht so aus:
Projekt Portable Class Library (Abgekürzt Mvvm.PCL)
MainViewModel.cs
ViewModelLocator.cs
Projekt Windows 8 Phone (Abgekürzt Mvvm.Phone) (deaktiviert)
Projekt Windows 8 App (Abgekürzt Mvvm.Store)
MainView.xaml
SecondView.xaml
ThirdView.xaml
MainPage.xamlMainPage.xaml beinhaltet eine AppBar mit Buttons und einen ContentController. Der ContentController soll die Views beinhalten.
Das ist die MainPage.xaml
Hier sieht man, dass ich bei den Buttons ein Command versuche (welches jedoch nicht funktioniert). Bei Klick auf dem Button soll sich die View im ContentControl dementsprechend anpassen (indem es in die MainViewModel.cs geht).
Beim Laden der MainPage soll als Anfangs-View die MainView.xaml verwendet werden (funktioniert auch nicht).Mehr kann jedoch in der ReadMe.txt, welche unten als Download vorhanden ist, gelesen werden.
<Page x:Name="pageRoot" x:Class="Mvvm.Store.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Mvvm.Store" xmlns:common="using:Mvvm.Store.Common" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" DataContext="{Binding Main, Source={StaticResource Locator}}"> <Grid Style="{StaticResource LayoutRootStyle}"> <Grid.RowDefinitions> <!-- View --> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- ContentControl should have MainView as first page on startup --> <ContentControl Name="MyContentControl" Grid.Row="0" Content="{Binding CurrentView}" IsTabStop="False" Margin="10" /> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="ApplicationViewStates"> <VisualState x:Name="FullScreenLandscape"/> <VisualState x:Name="Filled"/> <VisualState x:Name="FullScreenPortrait"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Padding"> <DiscreteObjectKeyFrame KeyTime="0" Value="96,136,86,56"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Snapped"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="pageTitle" Storyboard.TargetProperty="Style"> <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource SnappedPageHeaderTextStyle}"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemListView" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="itemGridView" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Grid> <!-- Bottom AppBar --> <Page.BottomAppBar> <AppBar IsOpen="True" x:Name="botAppBar" VerticalContentAlignment="Bottom" VerticalAlignment="Bottom"> <GridView x:Name="itemGridView" AutomationProperties.AutomationId="ItemsGridView" AutomationProperties.Name="Items" TabIndex="1" Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Top" HorizontalAlignment="Left" SelectionMode="Single" IsSwipeEnabled="false" IsItemClickEnabled="True" MaxHeight="100"> <!--"--> <Button Command="{Binding DisplayView}" CommandParameter="SecondView" Style="{StaticResource MyMenue}"> <Button.Content > <StackPanel> <TextBlock Text="SecondView" TextAlignment="Center"></TextBlock> </StackPanel> </Button.Content> </Button> <Button Command="{Binding DisplayView}" CommandParameter="ThirdView" Style="{StaticResource MyMenue}"> <Button.Content > <StackPanel> <TextBlock Text="ThirdView" TextAlignment="Center"></TextBlock> </StackPanel> </Button.Content> </Button> </GridView> </AppBar> </Page.BottomAppBar> </Page>
Meine App.xaml , wo das ViewModel der Portable Class Library verwendet wird.
<?xml version="1.0" encoding="utf-8"?> <Application x:Class="Mvvm.Store.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Mvvm.Store" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="using:Mvvm.PCL.ViewModel" mc:Ignorable="d"> <Application.Resources> <ResourceDictionary> <vm:ViewModelLocator p7:Key="Locator" p8:IsDataSource="True" xmlns:p8="http://schemas.microsoft.com/expression/blend/2008" xmlns:p7="http://schemas.microsoft.com/winfx/2006/xaml" /> <ResourceDictionary.MergedDictionaries> <!-- Styles that define common aspects of the platform look and feel Required by Visual Studio project and item templates --> <ResourceDictionary Source="Common/StandardStyles.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
Zuletzt noch das MainViewModel.cs , wo die Views gesetzt werden sollen.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; using GalaSoft.MvvmLight; using GalaSoft.MvvmLight.Command; #if NETFX_CORE using Mvvm.Store.Views; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #endif namespace Mvvm.PCL.ViewModel { /// <summary> /// This class contains properties that the main View can data bind to. /// <para> /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel. /// </para> /// <para> /// You can also use Blend to data bind with the tool's support. /// </para> /// <para> /// See http://www.galasoft.ch/mvvm /// </para> /// </summary> public class MainViewModel : ViewModelBase, INotifyPropertyChanged { /// <summary> /// Initializes a new instance of the MainViewModel class. /// </summary> public MainViewModel() { #if NETFX_CORE DisplayView = new RelayCommand<string>(DisplayViewCommandExecute); #endif } #if NETFX_CORE #region Commands public RelayCommand<string> DisplayView { get; private set; } #endregion #region CurrentView Property public const string CurrentViewPropertyName = "CurrentView"; private Page _currentView; public Page CurrentView { get { return _currentView; } set { if (_currentView == value) return; _currentView = value; RaisePropertyChanged(CurrentViewPropertyName); } } #endregion private void DisplayViewCommandExecute(string viewName) { switch (viewName) { case "SecondView": CurrentView = new SecondView(); break; case "ThirdView": CurrentView = new ThirdView(); break; } } #endif } }
Problem: Die Commands
Command="{Binding DisplayView}" CommandParameter="SecondView"
funktionieren nicht und ich weiß auch nicht, wie ich beim Starten der App das ContentControl mit der MainView.xaml befülle.
Mein Programm http://www10.zippyshare.com/v/29730402/file.html (Visual Studio 2012 benötigt (nicht Express))