这篇文章主要介绍了如何利用WPF实现一个简单的音频播放动画控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
1.实现代码
一、创建AnimationAudio.xaml代码如下
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WPFDevelopers.Controls"
xmlns:helpers="clr-namespace:WPFDevelopers.Helpers">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Basic/ControlBasic.xaml"/>
<ResourceDictionary Source="Basic/Animations.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type controls:AnimationAudio}" BasedOn="{StaticResource ControlBasicStyle}">
<Setter Property="Width" Value="80"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Foreground" Value="{DynamicResource WhiteSolidColorBrush}"/>
<Setter Property="Background" Value="{DynamicResource PrimaryNormalSolidColorBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:AnimationAudio}">
<ControlTemplate.Resources>
<Storyboard x:Key="PlayStoryboard" RepeatBehavior="Forever">
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PathAudioTwo" Storyboard.TargetProperty="(Path.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="PathAudioThree" Storyboard.TargetProperty="(Path.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Hidden}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:.3" Duration="0:0:.4" Storyboard.TargetName="PathAudioTwo"
Storyboard.TargetProperty="(Path.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="0:0:.7" Duration="0:0:.4" Storyboard.TargetName="PathAudioThree"
Storyboard.TargetProperty="(Path.Visibility)">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Border x:Name="PART_Border" Background="{TemplateBinding Background}"
CornerRadius="{TemplateBinding helpers:ControlsHelper.CornerRadius}"
SnapsToDevicePixels="True" UseLayoutRounding="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Width="20" Height="30" HorizontalAlignment="Left"
Orientation="Horizontal" Margin="10,0"
RenderTransformOrigin=".5,.5"
x:Name="PART_StackPanel">
<Path Data="{StaticResource PathAudioOne}" Width="4" Height="6"
Stretch="Fill" Fill="{TemplateBinding Foreground}"/>
<Path x:Name="PathAudioTwo" Data="{StaticResource PathAudioTwo}" Width="6" StrokeThickness="1.5"
Stroke="Transparent"
Margin="0,7" Stretch="Fill" Fill="{TemplateBinding Foreground}"/>
<Path x:Name="PathAudioThree" Data="{StaticResource PathAudioThree}" Width="8" Margin="-3,4" Stretch="Fill"
Fill="{TemplateBinding Foreground}" StrokeThickness="2" Stroke="Transparent"/>
</StackPanel>
<TextBlock VerticalAlignment="Center"
Foreground="{TemplateBinding Foreground}"
FontSize="{DynamicResource TitleFontSize}"
Grid.Column="1"
x:Name="PART_TextBlock">
<Run x:Name="PART_RunTimeLength"></Run>
</TextBlock>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsPlay" Value="True">
<Trigger.EnterActions>
<BeginStoryboard x:Name="PlayBeginStoryboard" Storyboard="{StaticResource PlayStoryboard}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<StopStoryboard BeginStoryboardName="PlayBeginStoryboard"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsRight" Value="True">
<Setter Property="Grid.Column" TargetName="PART_TextBlock" Value="0"/>
<Setter Property="HorizontalAlignment" TargetName="PART_TextBlock" Value="Right"/>
<Setter Property="Grid.Column" TargetName="PART_StackPanel" Value="1"/>
<Setter Property="HorizontalAlignment" TargetName="PART_StackPanel" Value="Right"/>
<Setter Property="RenderTransform" TargetName="PART_StackPanel">
<Setter.Value>
<TransformGroup>
<RotateTransform Angle="180"/>
</TransformGroup>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
二、创建AnimationAudioe.cs代码如下
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Interop;
using WPFDevelopers.Helpers;
namespace WPFDevelopers.Controls
{
[TemplatePart(Name = RunTemplateName, Type = typeof(Run))]
public partial class AnimationAudio : Control
{
const string RunTemplateName = "PART_RunTimeLength";
private Run _run;
private TimeSpan _timeSpan;
private IntPtr _handle;
private AudioWindow _win = null;
static string[] mediaExtensions = { ".MP3", ".WAV" };
/// <summary>
/// 音频路径
/// </summary>
public string AudioPath
{
get { return (string)GetValue(AudioPathProperty); }
set { SetValue(AudioPathProperty, value); }
}
public static readonly DependencyProperty AudioPathProperty =
DependencyProperty.Register("AudioPath", typeof(string), typeof(AnimationAudio), new PropertyMetadata(string.Empty));
/// <summary>
/// 是否右侧
/// </summary>
public bool IsRight
{
get { return (bool)GetValue(IsRightProperty); }
set { SetValue(IsRightProperty, value); }
}
public static readonly DependencyProperty IsRightProperty =
DependencyProperty.Register("IsRight", typeof(bool), typeof(AnimationAudio), new PropertyMetadata(false));
public bool IsPlay
{
get { return (bool)GetValue(IsPlayProperty); }
set { SetValue(IsPlayProperty, value); }
}
public static readonly DependencyProperty IsPlayProperty =
DependencyProperty.Register("IsPlay", typeof(bool), typeof(AnimationAudio), new PropertyMetadata(false, new PropertyChangedCallback(OnIsPlayChanged)));
private static void OnIsPlayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
bool newValue = (bool)e.NewValue;
var animationAudio = d as AnimationAudio;
if(newValue != (bool)e.OldValue)
{
if (newValue)
{
animationAudio.Play();
}
else
{
AudioPlayer.Stop();
}
}
}
static AnimationAudio()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimationAudio), new FrameworkPropertyMetadata(typeof(AnimationAudio)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_run = GetTemplateChild(RunTemplateName) as Run;
if (string.IsNullOrWhiteSpace(AudioPath)) return;
if (!File.Exists(AudioPath)) return;
if (!mediaExtensions.Contains(Path.GetExtension(AudioPath), StringComparer.OrdinalIgnoreCase)) return;
_timeSpan = AudioPlayer.GetSoundLength(AudioPath);
if (_timeSpan == TimeSpan.Zero) return;
_run.Text = $"{_timeSpan.Seconds.ToString()}\"";
Width = 80;
if (_timeSpan.Seconds > 5)
{
Width += _timeSpan.Seconds;
}
}
private void Play()
{
if(_win != null)
{
_win.Close();
_win = null;
}
_win = new AudioWindow
{
Width = 0,
Height = 0,
Left = Int32.MinValue,
Top = Int32.MinValue,
WindowStyle = WindowStyle.None,
ShowInTaskbar = false,
ShowActivated = false,
};
_win.Show();
_win.StopDelegateEvent += _win_StopDelegateEvent;
_handle = new WindowInteropHelper(_win).Handle;
AudioPlayer.PlaySong(AudioPath, _handle);
}
private void _win_StopDelegateEvent()
{
IsPlay = false;
_win.Close();
_win = null;
}
}
}
三、新建AudioWindow.cs代码如下
using System;
using System.Windows;
using System.Windows.Interop;
namespace WPFDevelopers.Controls
{
public class AudioWindow:Window
{
const int MM_MCINOTIFY = 0x3B9;
public delegate void StopDelegate();
public event StopDelegate StopDelegateEvent;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
if (hwndSource != null)
{
hwndSource.AddHook(new HwndSourceHook(this.WndProc));
}
}
IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case MM_MCINOTIFY:
StopDelegateEvent?.Invoke();
break;
}
return IntPtr.Zero;
}
}
}
四、新建AnimationAudioExample.xaml代码如下。
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.AnimationAudioExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UniformGrid Columns="2" x:Name="MyUniformGrid">
<StackPanel Orientation="Horizontal">
<wpfdev:BreathLamp Width="60" Height="60"
LampEffect="Ripple"
IsLampStart="true"
Margin="10,0">
<Ellipse Width="50" Height="50">
<Ellipse.Fill>
<ImageBrush ImageSource="pack://application:,,,/WPFDevelopers.Samples;component/Images/Breathe/0.jpg"/>
</Ellipse.Fill>
</Ellipse>
</wpfdev:BreathLamp>
<wpfdev:AnimationAudio x:Name="AnimationAudioLeft" MouseDown="AnimationAudioLeft_MouseDown"/>
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<wpfdev:AnimationAudio x:Name="AnimationAudioRight" IsRight ="true"
Background="{DynamicResource SuccessSolidColorBrush}"
Foreground="Black"
MouseDown="AnimationAudioLeft_MouseDown"/>
<wpfdev:BreathLamp Width="50" Height="50"
LampEffect="Streamer"
Background="LightGray"
IsLampStart="True"
Margin="10,0">
<Ellipse Width="43" Height="43">
<Ellipse.Fill>
<ImageBrush ImageSource="pack://application:,,,/WPFDevelopers.Samples;component/Images/Chat/UserImages/yanjinhua.png"/>
</Ellipse.Fill>
</Ellipse>
</wpfdev:BreathLamp>
</StackPanel>
</UniformGrid>
</UserControl>
六、新建AnimationAudioExample.xaml.cs下
using System;
using System.IO;
using System.Windows.Controls;
using WPFDevelopers.Controls;
using WPFDevelopers.Samples.Helpers;
namespace WPFDevelopers.Samples.ExampleViews
{
/// <summary>
/// 微信公众号:WPF开发者
/// </summary>
public partial class AnimationAudioExample : UserControl
{
public AnimationAudioExample()
{
InitializeComponent();
AnimationAudioLeft.AudioPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Audio", "HelloWPFDevelopes_en.mp3");
AnimationAudioRight.AudioPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Audio", "HelloWPFDevelopes_zh.mp3");
}
private void AnimationAudioLeft_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var animationAudio = sender as AnimationAudio;
var animationAudioList = ElementVisualTreeHelper.FindVisualChild<AnimationAudio>(MyUniformGrid);
if (animationAudioList == null) return;
if (!animationAudio.IsPlay)
{
animationAudioList.ForEach(h =>
{
if (h.IsPlay && h != animationAudio)
{
h.IsPlay = false;
}
});
animationAudio.IsPlay = true;
}
else
animationAudio.IsPlay = false;
}
}
}
2.效果预览
到此这篇关于基于WPF实现一个简单的音频播放动画控件的文章就介绍到这了,更多相关WPF音频播放动画控件内容请搜索得得之家以前的文章希望大家以后多多支持得得之家!
沃梦达教程
本文标题为:基于WPF实现一个简单的音频播放动画控件
基础教程推荐
猜你喜欢
- ZooKeeper的安装及部署教程 2023-01-22
- C#控制台实现飞行棋小游戏 2023-04-22
- C# windows语音识别与朗读实例 2023-04-27
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C#类和结构详解 2023-05-30
- C# 调用WebService的方法 2023-03-09
- winform把Office转成PDF文件 2023-06-14
- unity实现动态排行榜 2023-04-27
- C# List实现行转列的通用方案 2022-11-02
- 一个读写csv文件的C#类 2022-11-06