<wp8>_______关键帧动画(DoubleAnimationUsingKeyFrames)、自定义对话框

本文介绍如何在C#中实现一个自定义的Popup控件,该控件包含遮罩、主体区域和内容区域,支持自动关闭、显示故事和对话框等功能。通过使用XAML和WPF相关的API,实现了一个功能丰富的Popup组件,适用于Windows Phone应用开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<UserControl x:Class="CustCtrlClassLibrary.PopupView"
    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"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480" mc:Ignorable="d">

    <Grid x:Name="LayoutRoot">
        <Rectangle x:Name="mask" Fill="{StaticResource PhoneForegroundBrush}" Opacity="0" MouseLeftButtonDown="mask_MouseLeftButtonDown"/>
        <Grid x:Name="popupArea" VerticalAlignment="Center">
            <Grid.RenderTransform>
                <CompositeTransform x:Name="popupTransform"/>
            </Grid.RenderTransform>
            <Grid x:Name="contentArea" RenderTransformOrigin="0.5,0.5" Background="{StaticResource PhoneBackgroundBrush}">
                <Grid.RenderTransform>
                    <CompositeTransform/>
                </Grid.RenderTransform>
            </Grid>
        </Grid>
    </Grid>
    
</UserControl>
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Input;
using Microsoft.Phone.Shell;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using System.Windows.Media.Animation;
using System.Windows.Controls.Primitives;

namespace CustCtrlClassLibrary
{
    public partial class PopupView : UserControl
    {
        #region Constructor
        private bool IsAutoClose = true;
        private int storyType = 0;

        public PopupView(PhoneApplicationPage basePage, bool isAutoClose, int storytype = 0)
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(PopupCotainer_Loaded);
            _BasePage = basePage; IsAutoClose = isAutoClose; storyType = storytype;
            _BasePage.BackKeyPress += BasePage_BackKeyPress;
        }

        #endregion

        #region Property

        private PhoneApplicationPage _BasePage;
        private FrameworkElement _PopupContent { get; set; }
        Popup _Popup;
        CubicEase _EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseInOut };

        public bool IsShown
        {
            get
            {
                return _Popup.IsOpen;
            }
        }

        #endregion

        #region Private Method

        private void PopupCotainer_Loaded(object sender, RoutedEventArgs e)
        {
            if (_BasePage.ApplicationBar != null)
                _BasePage.ApplicationBar.IsVisible = false;
            if (storyType == 0) {
                PrepareShowStory().Begin();
            } else if (storyType == 1) {
                LaunchDialog().Begin();
            }
        }

        private void BasePage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.Close();
            e.Cancel = true;
        }

        private Storyboard PrepareShowStory()
        {
            contentArea.Children.Add(_PopupContent);
            UpdateLayout();

            Storyboard story = new Storyboard();
            DoubleAnimation animation;
            animation = new DoubleAnimation();
            animation.From = 0 - popupArea.ActualHeight;
            animation.To = SystemTray.IsVisible ? 32 : 0;
            animation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
            animation.EasingFunction = _EasingFunction;
            Storyboard.SetTarget(animation, popupTransform);
            Storyboard.SetTargetProperty(animation, new PropertyPath("TranslateY"));
            story.Children.Add(animation);

            animation = new DoubleAnimation();
            animation.From = 0;
            animation.To = 0.5;
            animation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
            Storyboard.SetTarget(animation, mask);
            Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.Opacity)"));
            story.Children.Add(animation);

            return story;
        }
        private Storyboard PrepareCloseStory()
        {
            Storyboard story = new Storyboard();
            DoubleAnimation animation;

            story.Completed += new EventHandler(StoryReverse_Completed);
            animation = new DoubleAnimation();
            animation.From = popupTransform.TranslateY;
            animation.To = 0 - popupArea.ActualHeight;
            animation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
            animation.EasingFunction = _EasingFunction;
            Storyboard.SetTarget(animation, popupTransform);
            Storyboard.SetTargetProperty(animation, new PropertyPath("TranslateY"));
            story.Children.Add(animation);

            animation = new DoubleAnimation();
            animation.From = mask.Opacity;
            animation.To = 0;
            animation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
            Storyboard.SetTarget(animation, mask);
            Storyboard.SetTargetProperty(animation, new PropertyPath("(UIElement.Opacity)"));
            story.Children.Add(animation);

            return story;
        }

        private Storyboard LaunchDialog()
        {
            contentArea.Children.Add(_PopupContent);
            UpdateLayout();

            //装载DoubleAnimationUsingKeyFrames动画的故事板
            Storyboard keyFrameboard = new Storyboard();

            #region 后台代码添加DoubleAnimationUsingKeyFrames动画
            DoubleAnimationUsingKeyFrames dakeyframe = new DoubleAnimationUsingKeyFrames();
            //设置border矩形控件的Opacity透明度,并且开始动画事件为0秒的时候。
            Storyboard.SetTarget(dakeyframe, contentArea);
            Storyboard.SetTargetProperty(dakeyframe, new PropertyPath("UIElement.Opacity"));
            dakeyframe.BeginTime = new TimeSpan(0, 0, 0);

            //添加一个在第0.05秒的时候Opacity透明度值为1的关键帧
            SplineDoubleKeyFrame SKeyFrame = new SplineDoubleKeyFrame();
            SKeyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.03));
            SKeyFrame.Value = 1;
            dakeyframe.KeyFrames.Add(SKeyFrame);

            keyFrameboard.Children.Add(dakeyframe);
            #endregion

            #region 后台代码添加DoubleAnimationUsingKeyFrames动画
            DoubleAnimationUsingKeyFrames dakeyscaleX = new DoubleAnimationUsingKeyFrames();
            //设置border矩形控件的ScaleX透明度,并且开始动画事件为0秒的时候。
            Storyboard.SetTarget(dakeyscaleX, contentArea);
            Storyboard.SetTargetProperty(dakeyscaleX, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.ScaleX)"));
            dakeyscaleX.BeginTime = new TimeSpan(0, 0, 0);

            //添加一个在第0秒的时候ScaleX透明度值为0.5的关键帧
            EasingDoubleKeyFrame EKeyFrameX = new EasingDoubleKeyFrame();
            EKeyFrameX.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
            EKeyFrameX.Value = 0.5;
            dakeyscaleX.KeyFrames.Add(EKeyFrameX);

            //添加一个在第0.15秒的时候ScaleX透明度值为1.1的关键帧
            EKeyFrameX = new EasingDoubleKeyFrame();
            EKeyFrameX.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.1));
            EKeyFrameX.Value = 1.1;
            dakeyscaleX.KeyFrames.Add(EKeyFrameX);

            //添加一个在第0.25秒的时候ScaleX透明度值为0.9的关键帧
            EKeyFrameX = new EasingDoubleKeyFrame();
            EKeyFrameX.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.2));
            EKeyFrameX.Value = 0.9;
            dakeyscaleX.KeyFrames.Add(EKeyFrameX);

            //添加一个在第0.3秒的时候ScaleX透明度值为0.9的关键帧
            EKeyFrameX = new EasingDoubleKeyFrame();
            EKeyFrameX.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.25));
            EKeyFrameX.Value = 1.0;
            dakeyscaleX.KeyFrames.Add(EKeyFrameX);

            keyFrameboard.Children.Add(dakeyscaleX);
            #endregion

            #region 后台代码添加DoubleAnimationUsingKeyFrames动画
            DoubleAnimationUsingKeyFrames dakeyscaleY = new DoubleAnimationUsingKeyFrames();
            //设置border矩形控件的ScaleY透明度,并且开始动画事件为0秒的时候。
            Storyboard.SetTarget(dakeyscaleY, contentArea);
            Storyboard.SetTargetProperty(dakeyscaleY, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.ScaleY)"));
            dakeyscaleY.BeginTime = new TimeSpan(0, 0, 0);

            //添加一个在第0秒的时候ScaleX透明度值为0.5的关键帧
            EasingDoubleKeyFrame EKeyFrameY = new EasingDoubleKeyFrame();
            EKeyFrameY.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
            EKeyFrameY.Value = 0.5;
            dakeyscaleY.KeyFrames.Add(EKeyFrameY);

            //添加一个在第0.15秒的时候ScaleX透明度值为1.1的关键帧
            EKeyFrameY = new EasingDoubleKeyFrame();
            EKeyFrameY.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.1));
            EKeyFrameY.Value = 1.1;
            dakeyscaleY.KeyFrames.Add(EKeyFrameY);

            //添加一个在第0.25秒的时候ScaleX透明度值为0.9的关键帧
            EKeyFrameY = new EasingDoubleKeyFrame();
            EKeyFrameY.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.2));
            EKeyFrameY.Value = 0.9;
            dakeyscaleY.KeyFrames.Add(EKeyFrameY);

            //添加一个在第0.3秒的时候ScaleX透明度值为0.9的关键帧
            EKeyFrameY = new EasingDoubleKeyFrame();
            EKeyFrameY.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.25));
            EKeyFrameY.Value = 1.0;
            dakeyscaleY.KeyFrames.Add(EKeyFrameY);

            keyFrameboard.Children.Add(dakeyscaleY);
            #endregion

            return keyFrameboard;
        }
        private Storyboard CloseDialog()
        {
            Storyboard keyFrameboard = new Storyboard();
            keyFrameboard.Completed += new EventHandler(StoryReverse_Completed);

            DoubleAnimation animation = new DoubleAnimation();
            //设置border矩形控件的Opacity透明度,并且开始动画事件为0秒的时候。
            Storyboard.SetTarget(animation, contentArea);
            Storyboard.SetTargetProperty(animation, new PropertyPath("UIElement.Opacity"));

            animation.From = 1; animation.To = 0.1;
            animation.Duration = new Duration(TimeSpan.FromSeconds(0.1));

            keyFrameboard.Children.Add(animation);

            return keyFrameboard;
        }

        private void StoryReverse_Completed(object sender, EventArgs e)
        {
            ClosePopup();
        }

        private void ClosePopup()
        {
            contentArea.Children.Clear();
            _PopupContent = null;
            _BasePage = null;

            Popup parent = this.Parent as Popup;
            if (parent != null)
            {
                parent.IsOpen = false;
            }
        }

        private void mask_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (IsAutoClose)
                Close();
        }

        #endregion

        #region Public Method

        public void Show(FrameworkElement popupContent)
        {
            _PopupContent = popupContent;
            _Popup = new Popup();
            _Popup.Child = this;
            _Popup.IsOpen = true;
        }

        public event PopUpClosed nPopUpClosed;

        public void Close()
        {
            _BasePage.BackKeyPress -= BasePage_BackKeyPress;
            if (storyType == 0) {
                PrepareCloseStory().Begin();
            } else if (storyType == 1) {
                CloseDialog().Begin();
            }
            if (_BasePage.ApplicationBar != null)
                _BasePage.ApplicationBar.IsVisible = true;
            if (nPopUpClosed != null)
                nPopUpClosed();
        }

        #endregion

        public void SetBackgroundColor(Brush aBrush)
        {
            contentArea.Background = aBrush;
        }
    }
}
CustCtrl parm = new CustCtrl();
PopupView pc = new PopupView(this, false, 1);
pc.Height = this.ActualHeight; pc.Width = this.ActualWidth;
SolidColorBrush nBrush = new SolidColorBrush(Color.FromArgb(25, 68, 68, 68));
pc.SetBackgroundColor(nBrush); 
pc.Show(parm);

 

转载于:https://www.cnblogs.com/qq278360339/archive/2013/03/29/2988611.html

InvalidOperationException: 无法在“System.Windows.Controls.ControlTemplate”的名称领域内找到“SwitchBorder”名称。 <CheckBox x:Name="BlurBgKg" Style="{DynamicResource SwitchBox}" Content="预览图动画开关" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,20,301,0" Background="#FFB9BEC2" BorderBrush="#FFB9BEC2" BorderThickness="0,0,0,0" Checked="BlurBgKg_Checked" Unchecked="BlurBgKg_Unchecked" IsChecked="True" Foreground="White"/> <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Style x:Key="FocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="OptionMarkFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <SolidColorBrush x:Key="OptionMark.Static.Background" Color="#FFFFFFFF"/> <SolidColorBrush x:Key="OptionMark.Static.Border" Color="#FF707070"/> <SolidColorBrush x:Key="OptionMark.Static.Glyph" Color="#FF212121"/> <SolidColorBrush x:Key="OptionMark.MouseOver.Background" Color="#FFF3F9FF"/> <SolidColorBrush x:Key="OptionMark.MouseOver.Border" Color="#FF5593FF"/> <SolidColorBrush x:Key="OptionMark.MouseOver.Glyph" Color="#FF212121"/> <SolidColorBrush x:Key="OptionMark.Pressed.Background" Color="#FFD9ECFF"/> <SolidColorBrush x:Key="OptionMark.Pressed.Border" Color="#FF3C77DD"/> <SolidColorBrush x:Key="OptionMark.Pressed.Glyph" Color="#FF212121"/> <SolidColorBrush x:Key="OptionMark.Disabled.Background" Color="#FFE6E6E6"/> <SolidColorBrush x:Key="OptionMark.Disabled.Border" Color="#FFBCBCBC"/> <SolidColorBrush x:Key="OptionMark.Disabled.Glyph" Color="#FF707070"/> <Storyboard x:Key="SwitchChecked"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)"> <EasingDoubleKeyFrame KeyTime="00:00:00" Value="12"/> <EasingDoubleKeyFrame KeyTime="00:00:00.1200000" Value="20"/> <EasingDoubleKeyFrame KeyTime="00:00:00.2400000" Value="12"/> </DoubleAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)"> <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Left}"/> <DiscreteObjectKeyFrame KeyTime="00:00:00.1200000" Value="{x:Static HorizontalAlignment.Right}"/> <DiscreteObjectKeyFrame KeyTime="00:00:00.2400000" Value="{x:Static HorizontalAlignment.Right}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> <Storyboard x:Key="SwitchUnchecked"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.Width)"> <EasingDoubleKeyFrame KeyTime="00:00:00" Value="12"/> <EasingDoubleKeyFrame KeyTime="00:00:00.1200000" Value="20"/> <EasingDoubleKeyFrame KeyTime="00:00:00.2400000" Value="12"/> </DoubleAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SwitchBorder" Storyboard.TargetProperty="(FrameworkElement.HorizontalAlignment)"> <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static HorizontalAlignment.Right}"/> <DiscreteObjectKeyFrame KeyTime="00:00:00.1200000" Value="{x:Static HorizontalAlignment.Left}"/> <DiscreteObjectKeyFrame KeyTime="00:00:00.2400000" Value="{x:Static HorizontalAlignment.Left}"/> </ObjectAnimationUsingKeyFrames> </Storyboard> <Style x:Key="SwitchBox" TargetType="{x:Type CheckBox}"> <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/> <Setter Property="Background" Value="{StaticResource OptionMark.Static.Background}"/> <Setter Property="BorderBrush" Value="{StaticResource OptionMark.Static.Border}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type CheckBox}"> <Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Border x:Name="PART_Border" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" BorderThickness="0" Height="16" Width="28" CornerRadius="8"> <Border x:Name="SwitchBorder" BorderThickness="0" BorderBrush="White" Background="White" Width="12" Height="12" Margin="2" CornerRadius="6" HorizontalAlignment="Left"/> </Border> <ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasContent" Value="true"> <Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual}"/> <Setter Property="Padding" Value="4,-1,0,0"/> </Trigger> <EventTrigger RoutedEvent="{x:Static CheckBox.CheckedEvent}"> <BeginStoryboard Storyboard="{StaticResource SwitchChecked}"/> </EventTrigger> <EventTrigger RoutedEvent="{x:Static CheckBox.UncheckedEvent}"> <BeginStoryboard Storyboard="{StaticResource SwitchUnchecked}"/> </EventTrigger> <Trigger Property="IsMouseOver" Value="true"> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Background}"/> <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.Disabled.Border}"/> </Trigger> <Trigger Property="IsPressed" Value="true"> </Trigger> <Trigger Property="IsChecked" Value="true"> <Setter Property="Background" TargetName="PART_Border" Value="#ffe8a741"/> <Setter Property="HorizontalAlignment" Value="Left" TargetName="SwitchBorder"/> </Trigger> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter Property="BorderBrush" TargetName="PART_Border" Value="{StaticResource OptionMark.MouseOver.Border}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
最新发布
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值