在mvvm中处理几个视图的问题

时间:2017-02-16 10:08:52

标签: c# wpf mvvm user-controls contentcontrol

我正在构建一个软件,他可以通过点击当前视图上的按钮来查看多个视图,并且我想从一个视图切换到另一个视图: enter image description here

当然我有3个以上的观点,但它是用来说明这个概念的。这是我从第1页到第2页的代码。但是我很难从第2页到第3页,我不知道错误。谢谢你的帮助。

MainWindow.xaml

<Controls:MetroWindow x:Class="maquette.MainWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"     
        xmlns:local="clr-namespace:maquette"
        xmlns:viewModel ="clr-namespace:maquette.ViewModel"
        xmlns:view ="clr-namespace:maquette.View"
        BorderBrush="{DynamicResource AccentColorBrush}"
        BorderThickness="2"
        mc:Ignorable="d"
        Title="MainWindow">

    <Window.Resources>
        <DataTemplate DataType="{x:Type viewModel:page1ViewModel}">
            <local:Page1/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModel:page2ViewModel}">
            <view:Page2/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModel:page3ViewModel}">
            <view:Page3/>
        </DataTemplate>
        <DataTemplate DataType="{x:Type viewModel:page4ViewModel}">
            <view:Page4/>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Controls:TransitioningContentControl x:Name="pagesControl"  
                                              Content="{Binding SelectedViewModel}"
                                              Transition="Left"
                                              />
    </Grid>

</Controls:MetroWindow>

MainWindow.cs

public MainWindow()
{
    InitializeComponent();

    var viewModel = new NavigationViewModel();

    viewModel.SelectedViewModel = new page1ViewModel(viewModel);

    this.DataContext = viewModel;
}

NavigationViewModel.cs

public class NavigationViewModel : INotifyPropertyChanged
{

    private object selectedViewModel;

    public object SelectedViewModel
    {
        get
        {
            return selectedViewModel;
        }
        set
        {
            selectedViewModel = value;
            OnPropertyChanged("SelectedViewModel");
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

的Page1.xaml

<UserControl x:Class="maquette.Page1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:maquette.View"
             xmlns:viewModel="clr-namespace:maquette.ViewModel"
             d:DesignHeight="300" d:DesignWidth="300"
             mc:Ignorable="d"       
             >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="100"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>


        <TextBlock x:Name="Title" 
                   HorizontalAlignment="Center" 
                   TextWrapping="Wrap" 
                   VerticalAlignment="Center" 
                   Width="320"  
                   FontSize="30"
                   Grid.ColumnSpan="2"
                   FontFamily="Segoe UI"
                   FontWeight="Bold">File Control Program</TextBlock>


        <Button x:Name="button" 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center"
                Grid.RowSpan="2"
                Width="180" 
                Height="90"
                Style="{StaticResource AccentedSquareButtonStyle}"
                Command="{Binding Path=goSettings}"
                >
            <TextBlock Text="go page 2"
                       TextWrapping="Wrap"
                       TextAlignment="Center"/>
        </Button>
    </Grid>
</UserControl>

page1ViewModel

class page1ViewModel
{
    public ICommand goSettings { get; set; }

    private readonly NavigationViewModel _navigationViewModel;

    public page1ViewModel(NavigationViewModel navigationViewModel)
    {
        _navigationViewModel = navigationViewModel;
        goSettings = new BaseCommand(OpenSettings);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="obj"></param>
    private void OpenSettings(object obj)
    {
        _navigationViewModel.SelectedViewModel = new page2ViewModel();
    }
}

page2.xaml

<UserControl x:Class="maquette.View.Page2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" 
             xmlns:local="clr-namespace:maquette.View"
             xmlns:view ="clr-namespace:maquette.View"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Background="White">

    <Grid>
        <Button x:Name="button" 
                HorizontalAlignment="Center" 
                VerticalAlignment="Center"
                Grid.ColumnSpan="2"
                Grid.Row="4"
                Width="180" 
                Height="80"
                Style="{StaticResource AccentedSquareButtonStyle}"
                Command="{Binding Path=goPage3}">
            <TextBlock Text="Go page 3"
                       TextWrapping="Wrap"
                       TextAlignment="Center"
                       FontSize="20"
                       />
        </Button>
    </Grid>
</UserControl>

page2.cs

public Page2()
{
     InitializeComponent();
     var viewModel = new NavigationViewModel();
     DataContext = new page2ViewModel(viewModel);
}

page2ViewModel.cs

    public class page2ViewModel
    {

        public ICommand goPage3 { get; set; }

        private readonly NavigationViewModel _navigationViewModel;

        public page2ViewModel()
        {

        }
        public page2ViewModel(NavigationViewModel navigationViewModel)
        {
            _navigationViewModel = navigationViewModel;
            goPage3 = new BaseCommand(OpenPage3);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj"></param>
        private void OpenPage3(object obj)
        {
            _navigationViewModel.SelectedViewModel = new page3ViewModel();
        }
}

但正如我所说,第2页和第3页之间的过渡并不奏效。任何帮助?谢谢 !

2 个答案:

答案 0 :(得分:1)

page2ViewModel

中删除此构造函数重载
public page2ViewModel()
{

}

并始终使用page1ViewModel中唯一的NavigationViewModel注入它:

private void OpenSettings(object obj)
{
    _navigationViewModel.SelectedViewModel = new page2ViewModel(_navigationViewModel);
}

另外,请勿明确设置DataContext的{​​{1}}:

Page2

数据模板将确保它获得正确的public Page2() { InitializeComponent(); }

答案 1 :(得分:0)

这是为了不使用任何mvvm框架

在主窗口视图模型中为子视图模型定义数据模板。

对于整个应用程序,您必须为主视图模型创建静态对象。

然后只会更改视图。

应该是这样的......

public partial class App : Application
{
    public static MainWindowViewModel mainWindowViewModel;

    public App()
    {
        mainWindowViewModel = new MainWindowViewModel();
    }
}

在MainWindow Viewmodel中

 public class MainWindowViewmodel
    {

        private object selectedViewModel;

        public object SelectedViewModel
        {
            get
            {
                return selectedViewModel;
            }
            set
            {
                selectedViewModel = value;
                OnPropertyChanged("SelectedViewModel");
            }
        }
        public MainWindowViewmodel()
        {
            SelectedViewModel = new page1viewmodel();
        }
    }

在Page1Viewmodel中

class page1ViewModel
{
public ICommand goSettings { get; set; }

private readonly NavigationViewModel _navigationViewModel;

public page1ViewModel(NavigationViewModel navigationViewModel)
{
    _navigationViewModel = navigationViewModel;
    goSettings = new BaseCommand(OpenSettings);
}
/// <summary>
/// 
/// </summary>
/// <param name="obj"></param>
private void OpenSettings(object obj)
{
   mainWindowViewModel.SelectedViewModel   = new page2ViewModel();
}

}

像这样你必须实施。

这会对你有帮助。