WPF开发者QQ群
此群已满340500857 ,请加新群458041663
由于微信群人数太多入群请添加小编微信号
yanjinhuawechat 或 W_Feng_aiQ 邀请入群
需备注WPF开发者
01
—
代码如下
一、创建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;}elseanimationAudio.IsPlay = false;}}
}
02
—
效果预览
鸣谢素材提供者 - 吴锋
源码地址如下
Github:https://github.com/WPFDevelopersOrg
Gitee:https://gitee.com/WPFDevelopersOrg
WPF开发者QQ群: 340500857 | 458041663
Github:https://github.com/WPFDevelopersOrg
出处:https://www.cnblogs.com/yanjinhua
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
转载请著名作者 出处 https://github.com/WPFDevelopersOrg
扫一扫关注我们,
更多知识早知道!
点击阅读原文可跳转至源代码