WPF 仿语音播放 自定义控件
2021-03-07 04:28
标签:template dem rom tco mat out idc 编写 collect
原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制。 控件基本是玩具,无法作为真实项目使用。 因为没有设置播放源,所以编写异步播放源或者实际播放时候要将事件引发,是否播放等属性,事件移到真实播放事件 非专业UI,即使知道怎么画图也是画的不如意,到底是眼睛会了,手不行啊。 主界面xaml 控件设计XAML 控件CS代码 WPF 仿语音播放 自定义控件 标签:template dem rom tco mat out idc 编写 collect 原文地址:https://www.cnblogs.com/lonelyxmas/p/12833879.html local:VoiceAnimeButton Height="40" Width="200" IconMargin="5,0,-8,0" HorizontalContentAlignment="Center" CornerRadius="15" VerticalContentAlignment="Center" BorderBrush="Black" IconFill="Black" BorderThickness="1" Background="Transparent" VoicePlayTime="0:0:1" >
local:VoiceAnimeButton.ContentTemplate>
DataTemplate>
TextBlock FontSize="10" >
Run Text="播放时间"/>
Run Text="{Binding RelativeSource={RelativeSource AncestorLevel=1,AncestorType=local:VoiceAnimeButton,Mode=FindAncestor}, Path=VoicePlayTime}"/>
Run Text=" "/>
Run Text="状态: "/>
Run Text="{Binding RelativeSource={RelativeSource AncestorLevel=1,AncestorType=local:VoiceAnimeButton,Mode=FindAncestor}, Path=IsVoicePlay}"/>
TextBlock>
DataTemplate>
local:VoiceAnimeButton.ContentTemplate>
local:VoiceAnimeButton>
ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:声音播放动画">
Style TargetType="{x:Type local:VoiceAnimeButton}">
Setter Property="Template">
Setter.Value>
ControlTemplate TargetType="{x:Type local:VoiceAnimeButton}">
Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" Padding="1">
Grid >
Grid.ColumnDefinitions>
ColumnDefinition Width="auto"/>
ColumnDefinition Width="*"/>
Grid.ColumnDefinitions>
Border Margin="{TemplateBinding IconMargin}" >
Viewbox>
Path x:Name="VoicePath" Height="{TemplateBinding IconHieght}" Width="{TemplateBinding IconWidth}" Fill="{TemplateBinding IconFill}" >
Path.Data>
PathGeometry>
PathFigureCollection>
M20 20 Q12 45 20 85 l7 -4 Q18 48 27 23 l-7 -3Z
M32 29 Q22 45 32 75 l7 -4 Q29 50 38 33 l-6.5 -4
M45 35 Q38 48 45 68 l7 -4 Q45 50 52 39 l-7.5 -4
M58 41 Q55 49 58 61 l17 -11Z
PathFigureCollection>
PathGeometry>
Path.Data>
Path>
Viewbox>
Border>
ContentPresenter Grid.Column="1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
Grid>
Border>
ControlTemplate.Triggers>
EventTrigger RoutedEvent="VoicePlayStart">
BeginStoryboard x:Name="bs1">
Storyboard Storyboard.TargetProperty="Data" Storyboard.TargetName="VoicePath" RepeatBehavior="Forever" Duration="0:0:0.4" BeginTime="0">
ObjectAnimationUsingKeyFrames>
DiscreteObjectKeyFrame KeyTime="0:0:0.1">
DiscreteObjectKeyFrame.Value>
PathGeometry>
PathFigureCollection>
M45 35 Q38 48 45 68 l7 -4 Q45 50 52 39 l-7.5 -4
M58 41 Q55 49 58 61 l17 -11Z
PathFigureCollection>
PathGeometry>
DiscreteObjectKeyFrame.Value>
DiscreteObjectKeyFrame>
DiscreteObjectKeyFrame KeyTime="0:0:0.2">
DiscreteObjectKeyFrame.Value>
PathGeometry>
PathFigureCollection>
M32 29 Q22 45 32 75 l7 -4 Q29 50 38 33 l-6.5 -4
M45 35 Q38 48 45 68 l7 -4 Q45 50 52 39 l-7.5 -4
M58 41 Q55 49 58 61 l17 -11Z
PathFigureCollection>
PathGeometry>
DiscreteObjectKeyFrame.Value>
DiscreteObjectKeyFrame>
DiscreteObjectKeyFrame KeyTime="0:0:0.3">
DiscreteObjectKeyFrame.Value>
PathGeometry>
PathFigureCollection>
M20 20 Q12 45 20 85 l7 -4 Q18 48 27 23 l-7 -3Z
M32 29 Q22 45 32 75 l7 -4 Q29 50 38 33 l-6.5 -4
M45 35 Q38 48 45 68 l7 -4 Q45 50 52 39 l-7.5 -4
M58 41 Q55 49 58 61 l17 -11Z
PathFigureCollection>
PathGeometry>
DiscreteObjectKeyFrame.Value>
DiscreteObjectKeyFrame>
ObjectAnimationUsingKeyFrames>
Storyboard>
BeginStoryboard>
EventTrigger>
EventTrigger RoutedEvent="VoicePlayEnd">
RemoveStoryboard BeginStoryboardName="bs1"/>
EventTrigger>
ControlTemplate.Triggers>
ControlTemplate>
Setter.Value>
Setter>
Style>
ResourceDictionary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace 声音播放动画
{
public class VoiceAnimeButton : ContentControl
{
static VoiceAnimeButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(VoiceAnimeButton), new FrameworkPropertyMetadata(typeof(VoiceAnimeButton)));
}
private DispatcherTimer Timer;
public VoiceAnimeButton()
{
Timer = new DispatcherTimer();
Timer.Tick += Timer_Tick;
Timer.Interval = TimeSpan.FromSeconds(1);
}
private void Timer_Tick(object sender, EventArgs e)
{
Timer.Stop();
IsVoicePlay = false;
this.RaiseEvent(new RoutedEventArgs(VoicePlayEndEvent, this));
}
public static readonly RoutedEvent VoicePlayStartEvent = EventManager.RegisterRoutedEvent("VoicePlayStart", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(VoiceAnimeButton));
///