【问题标题】:Making slide animation in wpf在wpf中制作幻灯片动画
【发布时间】:2018-06-02 20:15:37
【问题描述】:

我有一个网格,用作容器。 Grid 由 UserControl 组成,每一个都有 600px 的高度和 800px 的宽度。我想通过切换可见控件来制作类似演示文稿的幻灯片动画。 这是我的 mainWindow 的 xaml 代码:

<Window x:Class="MessengerWindowsClient.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:local="clr-namespace:MessengerWindowsClient"
    xmlns:pages="clr-namespace:MessengerWindowsClient.Pages"
    mc:Ignorable="d"
    Title="MainWindow" Height="600" Width="800" Closed="Window_Closed">
<Window.Background>
    <ImageBrush ImageSource="Resources/background.jpg"></ImageBrush>
</Window.Background>
<Grid x:Name="Container" RenderTransformOrigin="0.5,0.5" SizeChanged="Container_SizeChanged">
    <pages:WelcomePage x:Name ="WelcomePage" Visibility="Visible" RegisterPage="{Binding ElementName=RegisterPage}" LoginPage="{Binding ElementName=LoginPage}"/>
    <pages:MessagesPage Visibility="Collapsed"/>
    <pages:LoginPage x:Name="LoginPage" Visibility="Collapsed" WelcomePage="{Binding ElementName=WelcomePage}"/>
    <pages:RegisterPage x:Name="RegisterPage" Visibility="Collapsed" WelcomePage="{Binding ElementName=WelcomePage}"/>
</Grid>

下面是代码:

public partial class MainWindow : Window
{
    private ServiceManager _serviceManager;
    private UIElement _currentPage;

    public MainWindow()
    {
        InitializeComponent();
        _currentPage = this.Container.Children[0];
        this.RegisterPage.RegisterReady += RegisterUser;
        this.RegisterPage.ChangePage += ChangePage;
        this.WelcomePage.ChangePage += ChangePage;
        this.LoginPage.ChangePage += ChangePage;
        _serviceManager = new ServiceManager();
    }

    private void ChangePage(object sender, ChangePageEventArgs e)
    {
        switch (e.Direction)
        {
            case ChangePageDirection.Forward:
                AnimationManager.AnimateForwardPage(e.NewPage, e.OldPage, Container, this.ActualWidth);
                break;
            case ChangePageDirection.Backward:
                AnimationManager.AnimateBackwardPage(e.NewPage, e.OldPage, Container, this.ActualWidth);
                break;
        }
    }

    private async void RegisterUser(object sender, RegisterEventArgs e)
    {
        var isSucceed = await _serviceManager.RegisterUser(e.Name, e.Username, e.Password.ToString(), e.Email);
        e.Password.Dispose();
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        _serviceManager.Dispose();
    }

    private void Container_SizeChanged(object sender, SizeChangedEventArgs e)
    {

            UpdateLayout();
        }
    }
}

我尝试使用 this.ActualWidth,但它给出的值超过了我的显示分辨率。所以我的部分控制在屏幕后面。动画完成后它会返回。使用网格的任何宽度属性都会给出错误的值,即使在调整大小事件中使用 UpdateLayout()。

编辑: Screenshots

动画完成后和_container.HorizontalAlignment = HorizontalAlignment.Stretch;之后。

【问题讨论】:

  • 不确定我是否理解您想要实现的目标
  • 可能是this 可以帮忙

标签: c# wpf wpf-animation


【解决方案1】:

您是否要为某个 UI 元素的宽度或高度设置动画?您需要创建一个自定义动画类来扩展AnimationTimeline 并在XAML 中的Storyboard 内定义一个动画。 您将需要创建一个自定义类GridLengthAnimation

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;

namespace Infrastructure.Animations
{
    public class GridLengthAnimation : AnimationTimeline
    {
        protected override Freezable CreateInstanceCore()
        {
            return new GridLengthAnimation();
        }

        public override Type TargetPropertyType => typeof(GridLength);

        static GridLengthAnimation()
        {
            FromProperty = DependencyProperty.Register("From", typeof(GridLength),
                typeof(GridLengthAnimation));

            ToProperty = DependencyProperty.Register("To", typeof(GridLength),
                typeof(GridLengthAnimation));
        }

        public static readonly DependencyProperty FromProperty;
        public GridLength From
        {
            get => (GridLength)GetValue(GridLengthAnimation.FromProperty);
            set => SetValue(GridLengthAnimation.FromProperty, value);
        }

        public static readonly DependencyProperty ToProperty;
        public GridLength To
        {
            get => (GridLength)GetValue(GridLengthAnimation.ToProperty);
            set => SetValue(GridLengthAnimation.ToProperty, value);
        }

        public override object GetCurrentValue(object defaultOriginValue,
    object defaultDestinationValue, AnimationClock animationClock)
        {
            double fromVal = ((GridLength)GetValue(GridLengthAnimation.FromProperty)).Value;
            double toVal = ((GridLength)GetValue(GridLengthAnimation.ToProperty)).Value;
            if (fromVal > toVal)
            {
                return new GridLength((1 - animationClock.CurrentProgress.Value) *
                    (fromVal - toVal) + toVal, GridUnitType.Pixel);
            }
            else
            {
                return new GridLength(animationClock.CurrentProgress.Value *
                    (toVal - fromVal) + fromVal, GridUnitType.Pixel);
            }
        }
    }
}

然后您可以在 XAML 中的 Storyboard 中使用它,如下所示:

<Storyboard x:Key="storyboardName">
            <support:GridLengthAnimation Storyboard.TargetName="YourElementToAnimate" Storyboard.TargetProperty="Width" From="{Binding StartAnimationWidth}" To="{Binding EndAnimationWidth}" DecelerationRatio="0.9" Duration="0:0:0.6"/>            
</Storyboard>

StartAnimationWidthEndAnimationWidthGridLength 类型的属性,在 ViewModel 中定义

private GridLength _endAnimationWidth = new GridLength(100);
public GridLength EndAnimationWidth
{
    get => _endAnimationWidth;
    set => SetProperty(ref _endAnimationWidth,value);
}

然后您可以从后面的代码中触发动画:

Storyboard sb = Resources["storyboardName"] as Storyboard;
sb.Begin();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多