WPF使用Animation仿WeChat(微信)播放语音消息
程序员文章站
2023-03-26 16:05:33
效果图预览 新建MyCustomControl类。 public class MyCustomControl : Control { private static Storyboard MyStory; private ObjectAnimationUsingKeyFrames MyAnimatio ......
效果图预览
新建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张)。
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; } }