WPF中视图/视图模型之间转换的可重用/简洁方式,无需代码隐藏

WPF中视图/视图模型之间转换的可重用/简洁方式,无需代码隐藏,wpf,mvvm,Wpf,Mvvm,什么 这个问题困扰了我好几个月,但我终于找到了一种在WPF中在视图之间转换的通用方法——一种允许我在转换中使用任何动画的方法。不,VisualStateManager在这里一点帮助都没有——它只适用于同一视图中的转换。已经有了一些框架和技术,但坦率地说,它们都把我弄糊涂了,或者看起来很笨拙。还好,但我不太喜欢它,因为某种原因,我晚上睡不着觉。也许,虽然比大多数人都简单,但它似乎仍然令人困惑,所以我明白了它的要点,并制定了自己的。然而,它确实启发了我的解决方案 所以我导入了我的助手库,下面是在视图

什么


这个问题困扰了我好几个月,但我终于找到了一种在WPF中在视图之间转换的通用方法——一种允许我在转换中使用任何动画的方法。不,VisualStateManager在这里一点帮助都没有——它只适用于同一视图中的转换。

已经有了一些框架和技术,但坦率地说,它们都把我弄糊涂了,或者看起来很笨拙。还好,但我不太喜欢它,因为某种原因,我晚上睡不着觉。也许,虽然比大多数人都简单,但它似乎仍然令人困惑,所以我明白了它的要点,并制定了自己的。然而,它确实启发了我的解决方案

所以我导入了我的助手库,下面是在视图之间进行转换所需的唯一代码。您可以使用任何想要的动画,而不仅仅是我的淡入/淡出动画。如果有人让我知道上传我的解决方案的好地方,我很乐意与大家分享

代码

有一个带有红色框(RedGridViewModel)和蓝色框(BlueGridViewModel)的窗口。每个框下面都有一个按钮,可以交替地将框更改为当前未更改的颜色。按下按钮时,当前框淡出,新框淡入。当转换发生时,按钮被禁用,两个按钮可以快速连续按下,而不会使程序崩溃。我在这里使用了两个从属ViewModel,但是您可以使用任意数量的ViewModel

<Window x:Class="ViewModelTransitionTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ViewModelTransitionTest"
    xmlns:custom="clr-namespace:CustomTools;assembly=CustomTools"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{x:Static local:StartingDataContext.DataContext}">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--Reference to my helper library with all the goodies that make this whole thing work somehow-->
            <ResourceDictionary Source="pack://application:,,,/CustomTools;component/ViewModelTransition/TransitionCapableViewModelResources.xaml"/>
            <!--DataTemplates for the Red and Blue view models.  Just tack on 
            the TransitionCapableViewModelStyleWithFadeInAndOut style and you're good to go.-->
            <ResourceDictionary>
                <DataTemplate DataType="{x:Type local:BlueGridViewModel}">
                    <Grid
                        Background="Blue"
                        Opacity="0"
                        Style="{StaticResource TransitionCapableViewModelStyleWithFadeInAndOut}"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:RedGridViewModel}">
                    <Grid 
                        Background="Red"
                        Opacity="0"
                        Style="{StaticResource TransitionCapableViewModelStyleWithFadeInAndOut}"/>
                </DataTemplate>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <ContentPresenter 
        Content="{Binding ViewModelA}"
        Grid.Row="0"
        Grid.Column="0"/>
    <ContentPresenter 
        Content="{Binding ViewModelB}"
        Grid.Row="0"
        Grid.Column="1"/>
    <Button
        Content="Change ViewModel"
        Grid.Row="1"
        Grid.Column="0"
        Command="{Binding ChangeViewModelA}"/>
    <Button 
        Content="Change ViewModel"
        Grid.Row="1"
        Grid.Column="1"
        Command="{Binding ChangeViewModelB}"/>
</Grid>

我利用了以下方面:


如果有兴趣,我可以发布管道代码或上传整个解决方案。其实没那么长——两个基类,一个包含两种样式和两个故事板的资源文件。

已经有了框架和技术,但坦率地说,它们都把我弄糊涂了,或者看起来很笨重。还好,但我不太喜欢它,因为某种原因,我晚上睡不着觉。也许,虽然比大多数人都简单,但它似乎仍然令人困惑,所以我明白了它的要点,并制定了自己的。然而,它确实启发了我的解决方案

所以我导入了我的助手库,下面是在视图之间进行转换所需的唯一代码。您可以使用任何想要的动画,而不仅仅是我的淡入/淡出动画。如果有人让我知道上传我的解决方案的好地方,我很乐意与大家分享

代码

有一个带有红色框(RedGridViewModel)和蓝色框(BlueGridViewModel)的窗口。每个框下面都有一个按钮,可以交替地将框更改为当前未更改的颜色。按下按钮时,当前框淡出,新框淡入。当转换发生时,按钮被禁用,两个按钮可以快速连续按下,而不会使程序崩溃。我在这里使用了两个从属ViewModel,但是您可以使用任意数量的ViewModel

<Window x:Class="ViewModelTransitionTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ViewModelTransitionTest"
    xmlns:custom="clr-namespace:CustomTools;assembly=CustomTools"
    Title="MainWindow" Height="350" Width="525"
    DataContext="{x:Static local:StartingDataContext.DataContext}">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!--Reference to my helper library with all the goodies that make this whole thing work somehow-->
            <ResourceDictionary Source="pack://application:,,,/CustomTools;component/ViewModelTransition/TransitionCapableViewModelResources.xaml"/>
            <!--DataTemplates for the Red and Blue view models.  Just tack on 
            the TransitionCapableViewModelStyleWithFadeInAndOut style and you're good to go.-->
            <ResourceDictionary>
                <DataTemplate DataType="{x:Type local:BlueGridViewModel}">
                    <Grid
                        Background="Blue"
                        Opacity="0"
                        Style="{StaticResource TransitionCapableViewModelStyleWithFadeInAndOut}"/>
                </DataTemplate>
                <DataTemplate DataType="{x:Type local:RedGridViewModel}">
                    <Grid 
                        Background="Red"
                        Opacity="0"
                        Style="{StaticResource TransitionCapableViewModelStyleWithFadeInAndOut}"/>
                </DataTemplate>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <ContentPresenter 
        Content="{Binding ViewModelA}"
        Grid.Row="0"
        Grid.Column="0"/>
    <ContentPresenter 
        Content="{Binding ViewModelB}"
        Grid.Row="0"
        Grid.Column="1"/>
    <Button
        Content="Change ViewModel"
        Grid.Row="1"
        Grid.Column="0"
        Command="{Binding ChangeViewModelA}"/>
    <Button 
        Content="Change ViewModel"
        Grid.Row="1"
        Grid.Column="1"
        Command="{Binding ChangeViewModelB}"/>
</Grid>

我利用了以下方面:

如果有兴趣,我可以发布管道代码或上传整个解决方案。它并没有那么长——两个基类,一个资源文件,有两种样式和两个故事板

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CustomTools;

namespace ViewModelTransitionTest
{
    static class StartingDataContext
    {
        public static MainWindowViewModel DataContext { 
            get 
            { 
                return new MainWindowViewModel(new BlueGridViewModel(), new RedGridViewModel()); 
            } 
        }
    }

    class RedGridViewModel : TransitionCapableViewModel
    {
    }

    class BlueGridViewModel : TransitionCapableViewModel
    {
    }
}