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.xaml

    MainPage.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))


Log in to reply