欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

WPF使用Animation仿WeChat(微信)播放语音消息

程序员文章站 2022-05-28 23:10:11
效果图预览 新建MyCustomControl类。 public class MyCustomControl : Control { private static Storyboard MyStory; private ObjectAnimationUsingKeyFrames MyAnimatio ......

效果图预览

WPF使用Animation仿WeChat(微信)播放语音消息

 

新建mycustomcontrol类。

 public class mycustomcontrol : control
    {
        private static storyboard mystory;
        private objectanimationusingkeyframes myanimation;
        private list<bitmapimage> imagelist;

        private uielement animation;

        public static readonly dependencyproperty durationproperty =
             dependencyproperty.register("duration", typeof(timespan),
             typeof(mycustomcontrol), new propertymetadata(null));

        /// <summary>
        /// 动画时间
        /// </summary>
        public timespan duration
        {
            get { return (timespan)getvalue(durationproperty); }
            set { setvalue(durationproperty, value); }
        }

        public static readonly dependencyproperty islitproperty =
             dependencyproperty.register("islit", typeof(bool),
             typeof(mycustomcontrol), new propertymetadata(false, new propertychangedcallback(onislitchanged)));

        /// <summary>
        /// 是否开始播放
        /// </summary>
        public bool islit
        {
            get { return (bool)getvalue(islitproperty); }
            set { setvalue(islitproperty, value); }
        }

        public override void onapplytemplate()
        {
            base.onapplytemplate();
            animation = template.findname("animation", this) as uielement;
            if (animation != null && islit)
                animate(animation);

        }

        private static void onislitchanged(dependencyobject d, dependencypropertychangedeventargs e)
        {
            bool newvalue = (bool)e.newvalue;
            if (newvalue)
            {
                mycustomcontrol c = d as mycustomcontrol;
                if (c != null && c.animation != null)
                {
                    c.animate(c.animation);
                }
            }
            else
            {
                mystory.stop();
            }
        }

        private void animate(uielement animation)
        {
            int count = 0;//计数
            for (double i = duration.totalseconds; i > 1; i--)
            {
                if (count > 2)
                {
                    count = 0;
                }
                myanimation.keyframes.add(
                   new discreteobjectkeyframe()
                   {
                       value = imagelist[count],
                       keytime = keytime.fromtimespan(timespan.fromseconds(duration.totalseconds - i))
                   });
                count++;
            }
            storyboard.settarget(myanimation, animation);
            storyboard.settargetproperty(myanimation,new propertypath(image.sourceproperty));
            mystory.children.add(myanimation);//将动画添加到动画板中

            console.writeline($"一共添加:{myanimation.keyframes.count} 个 discreteobjectkeyframe。");
            mystory.begin();
        }
        public mycustomcontrol()
        {
            mystory = new storyboard();
            myanimation = new objectanimationusingkeyframes();
            myanimation.fillbehavior = fillbehavior.stop;

            myanimation.completed += (s, args) => 
            {
                islit = false;
            };

            imagelist = new list<bitmapimage>();
            imagelist.add(new bitmapimage(new uri("pack://application:,,,/images/0.png")));
            imagelist.add(new bitmapimage(new uri("pack://application:,,,/images/1.png")));
            imagelist.add(new bitmapimage(new uri("pack://application:,,,/images/2.png")));
            

        }
    }

修改mainwindow.xaml。

<window x:class="wpfanimationwechat.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:wpfanimationwechat"
        mc:ignorable="d" windowstate="maximized"
        title="mainwindow" height="450" width="800">
    <window.resources>
        <controltemplate x:key="ct" targettype="local:mycustomcontrol">
            <image x:name="animation" height="20" width="20" source="/wpfanimationwechat;component/images/2.png"/>
        </controltemplate>
    </window.resources>
    <grid>
        <viewbox>
            <grid width="1240" height="768">
                <grid height="28" width="100" mouseleftbuttondown="grid_mouseleftbuttondown">
                    <rectangle radiusx="4" radiusy="4" fill="#9eea6a" />
                    <stackpanel orientation="horizontal" margin="4,0">
                        <!--可以设置mycustomcontrol的duration 和 islit(点击的时候执行)的{binding}-->
                        <local:mycustomcontrol x:name="audioplay" template="{staticresource ct}" duration="0:00:10" islit="false"/>
                        <textblock text="10ms”" verticalalignment="center" fontsize="20"/>
                </stackpanel>
            </grid>
            </grid>
            
        </viewbox>
    </grid>
</window>

新增资源(3张)。

WPF使用Animation仿WeChat(微信)播放语音消息

 

mainwindow.xaml.cs新增grid_mouseleftbuttondown。

 

private void grid_mouseleftbuttondown(object sender, mousebuttoneventargs e)
        {
            if (this.audioplay.islit)
            {
                 this.audioplay.islit = false;
            }
            else
            {
                this.audioplay.islit = true;
            }
        }