接上篇。前面我们实现了页面切换时,以动画的形式加载,虽然我们在设计之初我们添加了页面卸载动画功能块,但实际上卸载的动画从没有出现过。本文主要针对自定义动画为主题,继续完成页面卸载时的动画效果。
首先上效果:
定义两个容器(F1和F2),F1用于存放新的页面,F2用户保存旧的页面。利用页面加载时执行动画,实现动画效果。当页面切换时,根据两个容器的特性,加载对应的动画,实现页面出现或者消失动画效果。即:F1容器上的页面执行加载(出现)动画,F2容器上的页面执行卸载(消失)动画。
Windows 10
Visual Studio 2019
.Net Framework 4.7.2
UI设计:
和上篇文章相同。
功能设计:
1.页面进入加载时,使用淡入或滑入的动画效果。
2.页面退出卸载时,使用淡出或滑出的动画效果。
(1)HostView控件
(2)使用依赖属性显示当前页面
using System.Windows;
using System.Windows.Controls;
namespace Deamon.View
{
///
/// ViewHost.xaml 的交互逻辑
///
public partial class ViewHost : UserControl
{
public ViewHost()
{
InitializeComponent();
}
#region 依赖属性
///
/// 在 ViewHost 中显示的当前页面
///
public AnimationPageBaseView CurrentView
{
get => (AnimationPageBaseView)GetValue(CurrentPageProperty);
set => SetValue(CurrentPageProperty, value);
}
///
/// 注册依赖属性
///
public static readonly DependencyProperty CurrentPageProperty =
DependencyProperty.Register(nameof(CurrentView), typeof(AnimationPageBaseView), typeof(ViewHost), new UIPropertyMetadata(CurrentPagePropertyChanged));
#region 属性更改事件
///
/// 当 值发生变化时调用
///
/// 依赖对象
/// 依赖属性值发生变化的参数
private static void CurrentPagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// 获取Frame
var newPageFrame = (d as ViewHost).NewPage;
var oldPageFrame = (d as ViewHost).OldPage;
// 将当前页内容存储为旧页
var oldPageContent = newPageFrame.Content;
// 删除当前页
newPageFrame.Content = null;
// 将上一页(旧页)移到 oldPageFrame 里面
oldPageFrame.Content = oldPageContent;
// 以动画的方式移除上一页
if (oldPageContent is AnimationPageBaseView oldPage)
{ oldPage.ShouldAnimationOut = true; }
// 设置当前页的内容
newPageFrame.Content = e.NewValue;
}
#endregion
#endregion
}
}
using Deamon.Util.Animation;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace Deamon.View
{
public class AnimationPageBaseView :Page
{
#region 公共属性
///
/// 加载页面动画方向 默认值为None表示只有淡出效果,没有滑动效果
///
public AnimationSlideInDirection PageLoadAnimationDirection { get; set; } = AnimationSlideInDirection.None;
///
/// 卸载页面动画方向 默认值为None表示只有淡出效果,没有滑动效果
///
public AnimationSlideInDirection PageUnloadAnimationDirection { get; set; } = AnimationSlideInDirection.None;
///
/// 标识在加载时,是否需要使用动画退出
/// 用于将页面移动到另外的一个Frame容器上
///
public bool ShouldAnimationOut { get; set; } = false;
///
/// 滑动时间
///
public float SlideSeconds { get; set; } = 0.5f;
#endregion
#region 构造函数
///
/// 默认构造函数
///
public AnimationPageBaseView()
{
// 让设计时,不去制作动画(不添加这个,设计界面会弹出“NullReferenceException”)
if (DesignerProperties.GetIsInDesignMode(this))
{ return; }
// 如果需要以动画的方式进入,首先将该页影藏
if (PageLoadAnimationDirection != AnimationSlideInDirection.None)
{ Visibility = Visibility.Collapsed; }
// 监听页面加载
Loaded += BasePage_LoadedAsync;
}
#endregion
#region 根据页面属性,实现动画加载和卸载
///
/// 一旦页面加载,执行必要的动画
///
///
///
private async void BasePage_LoadedAsync(object sender, System.Windows.RoutedEventArgs e)
{
if (ShouldAnimationOut)
{
// Animation out the page
await AnimateOutAsync();
}
// Otherwise...
else
{
// Animate the page in
await AnimateInAsync();
}
}
///
/// 以动画的方式进入
///
///
public async Task AnimateInAsync()
{
// 开始动画
await this.SlideAndFadeInAsync(PageLoadAnimationDirection, false, SlideSeconds, size: (int)Application.Current.MainWindow.Width);
}
///
/// 以动画的方式退出
///
///
public async Task AnimateOutAsync()
{
// 开始动画
await this.SlideAndFadeOutAsync(PageUnloadAnimationDirection, SlideSeconds);
}
#endregion
}
}
///
/// LoginView.xaml 的交互逻辑
///
public partial class LoginView : AnimationPageBaseView
{
public LoginView()
{
InitializeComponent();
PageLoadAnimationDirection = Util.Animation.AnimationSlideInDirection.None;
PageUnloadAnimationDirection = Util.Animation.AnimationSlideInDirection.Left;
}
}
///
/// HomeView.xaml 的交互逻辑
///
public partial class HomeView : AnimationPageBaseView
{
public HomeView()
{
InitializeComponent();
PageLoadAnimationDirection = Util.Animation.AnimationSlideInDirection.Right;
PageUnloadAnimationDirection = Util.Animation.AnimationSlideInDirection.Left;
}
}
///
/// ChamberView.xaml 的交互逻辑
///
public partial class ChamberView : AnimationPageBaseView
{
public ChamberView()
{
InitializeComponent();
PageLoadAnimationDirection = Util.Animation.AnimationSlideInDirection.Bottom;
PageUnloadAnimationDirection = Util.Animation.AnimationSlideInDirection.Top;
}
}
///
/// RecordView.xaml 的交互逻辑
///
public partial class RecordView : AnimationPageBaseView
{
public RecordView()
{
InitializeComponent();
PageLoadAnimationDirection = Util.Animation.AnimationSlideInDirection.Top;
PageUnloadAnimationDirection = Util.Animation.AnimationSlideInDirection.Bottom;
}
}
///
/// SettingsView.xaml 的交互逻辑
///
public partial class SettingsView : AnimationPageBaseView
{
public SettingsView()
{
InitializeComponent();
PageLoadAnimationDirection = Util.Animation.AnimationSlideInDirection.Left;
PageUnloadAnimationDirection = Util.Animation.AnimationSlideInDirection.Right;
}
}
Over
每次记录一小步...点点滴滴人生路...