返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C# WPF实现的语音播放自定义控件
  • 836
分享到

C# WPF实现的语音播放自定义控件

2024-04-02 19:04:59 836人浏览 八月长安
摘要

目录主界面xaml控件设计XAML控件CS代码原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制。 控件基本是玩具,无

原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制。

控件基本是玩具,无法作为真实项目使用。

因为没有设置播放源,所以编写异步播放源或者实际播放时候要将事件引发,是否播放等属性,事件移到真实播放事件

非专业UI,即使知道怎么画图也是画的不如意,到底是眼睛会了,手不行啊。

主界面xaml


<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>

控件设计XAML


<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>

控件CS代码


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));

    /// <summary>
    /// 声音播放开始事件
    /// </summary>
    public event RoutedEventHandler VoicePlayStart
    {
      add
      {
        this.AddHandler(VoicePlayStartEvent, value);
      }
      remove
      {
        RemoveHandler(VoicePlayStartEvent, value);
      }
    }


    public static readonly RoutedEvent VoicePlayEndEvent= EventManager.RegisterRoutedEvent("VoicePlayEnd", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(VoiceAnimeButton));

    /// <summary>
    /// 声音播放结束事件
    /// </summary>
    public event RoutedEventHandler VoicePlayEnd
    {
      add
      {
        AddHandler(VoicePlayEndEvent, value);
      }
      remove
      {
        RemoveHandler(VoicePlayEndEvent, value);
      }
    }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
      base.OnMouseLeftButtonDown(e);
      IsMouseLeftClick = true;
      Timer.Interval = VoicePlayTime;
      Timer.Start();
      IsVoicePlay = true;
      this.RaiseEvent(new RoutedEventArgs(VoicePlayStartEvent,this));
      
    }
    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
      base.OnMouseLeftButtonUp(e);
      IsMouseLeftClick = false;
    }

    public static readonly DependencyProperty VoicePlayTimeProperty = DependencyProperty.Register("VoicePlayTime", typeof(TimeSpan), typeof(VoiceAnimeButton), new PropertyMetadata(TimeSpan.FromMilliseconds(1000)));
   
    public TimeSpan VoicePlayTime
    {
      get => (TimeSpan)GetValue(VoicePlayTimeProperty);
      set => SetValue(VoicePlayTimeProperty, value);
    }
    public static readonly DependencyProperty IsMouseLeftClickProperty = DependencyProperty.Register("IsMouseLeftClick", typeof(bool), typeof(VoiceAnimeButton),new PropertyMetadata(false));

    public bool IsMouseLeftClick
    {
      get => (bool)GetValue(IsMouseLeftClickProperty);
      set => SetValue(IsMouseLeftClickProperty, value);
    }
    public static readonly DependencyProperty IconWidthProperty = DependencyProperty.Register("IconWidth", typeof(double), typeof(VoiceAnimeButton), new PropertyMetadata(100.0));

    public double IconWidth
    {
      get => Convert.ToDouble(IconWidthProperty);
      set => SetValue(IconWidthProperty, value);
    }
    public static readonly DependencyProperty IconHieghtProperty = DependencyProperty.Register("IconHieght", typeof(double), typeof(VoiceAnimeButton), new PropertyMetadata(100.0));

    public double IconHieght
    {
      get => Convert.ToDouble(IconHieghtProperty);
      set => SetValue(IconHieghtProperty, value);
    }

    public static readonly DependencyProperty IconFillProperty= DependencyProperty.Register("IconFill", typeof(SolidColorBrush), typeof(VoiceAnimeButton), new PropertyMetadata(new SolidColorBrush(Colors.Black)));

    public SolidColorBrush IconFill
    {
      get => GetValue(IconFillProperty) as SolidColorBrush;
      set => SetValue(IconFillProperty, value);
    }

    public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(VoiceAnimeButton), new PropertyMetadata(new CornerRadius(0)));

    public CornerRadius CornerRadius
    {
      get => (CornerRadius)GetValue(CornerRadiusProperty);
      set => SetValue(CornerRadiusProperty, value);
    }
    public static readonly DependencyProperty IconMarginProperty = DependencyProperty.Register("IconMargin", typeof(Thickness), typeof(VoiceAnimeButton), new PropertyMetadata(new Thickness(0.0)));

    public Thickness IconMargin
    {
      get => (Thickness)GetValue(IconMarginProperty);
      set => SetValue(IconMarginProperty, value);
    }

    public static readonly DependencyProperty IsVoicePlayProperty = DependencyProperty.Register("IsVoicePlay", typeof(bool), typeof(VoiceAnimeButton));

    public bool IsVoicePlay
    {
      get => (bool)GetValue(IsVoicePlayProperty);
      set => SetValue(IsVoicePlayProperty, value);
    }
  }
}

以上就是C# WPF实现的语音播放自定义控件的详细内容,更多关于WPF实现语音播放自定义控件的资料请关注编程网其它相关文章!

--结束END--

本文标题: C# WPF实现的语音播放自定义控件

本文链接: https://lsjlt.com/news/123026.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C# WPF实现的语音播放自定义控件
    目录主界面xaml控件设计XAML控件CS代码原理很简单,利用Path画一个图,然后用动画进行播放,播放时间由依赖属性输入赋值与控件内部维护的一个计时器进行控制。 控件基本是玩具,无...
    99+
    2024-04-02
  • WPF自定义控件的实现
    方式一:基于现有控件进行扩展,如基于button进行扩展,UI可直接用xmal进行编辑设计,逻辑用xaml.cs进行编辑 方法二:直接创建wpf自定义控件 本文用方法二开展自定义...
    99+
    2023-03-03
    WPF自定义控件
  • WPF自定义控件如何实现
    今天小编给大家分享一下WPF自定义控件如何实现的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。方式一:基于现有控件进行扩展,如...
    99+
    2023-07-05
  • Android自定义播放器控件VideoView
    介绍 最近要使用播放器做一个简单的视频播放功能,开始学习VideoView,在横竖屏切换的时候碰到了点麻烦,不过在查阅资料后总算是解决了。在写VideoView播放视频时候定...
    99+
    2022-06-06
    videoview Android
  • 基于WPF实现一个简单的音频播放动画控件
    目录1.实现代码2.效果预览1.实现代码 一、创建AnimationAudio.xaml代码如下 <ResourceDictionary xmlns="http://schem...
    99+
    2024-04-02
  • Android自定义控件实现简单的轮播图控件
    最近要做一个轮播图的效果,网上看了几篇文章,基本上都能找到实现,效果还挺不错,但是在写的时候感觉每次都要单独去重新在Activity里写一堆代码。于是自己封装了一下。本篇轮播图...
    99+
    2022-06-06
    轮播图 轮播 Android
  • WPF自定义Expander控件样式实现酷炫Style
    首先, 看一下效果图。 点我看视频教程 实现思路 1.PS处理两张选中得特效背景, 一张为主选择得效果图, 另外一张为次选择项得效果图。 ![](//img.jbzj.com/fi...
    99+
    2024-04-02
  • 如何实现自定义html5播放器
    这篇文章给大家分享的是有关如何实现自定义html5播放器的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。效果预览点我查看 源码仓库 。核心思路我相信一定会有些没有接触过制作自定义播...
    99+
    2024-04-02
  • html5如何实现自定义播放器
    这篇文章主要为大家展示了“html5如何实现自定义播放器”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“html5如何实现自定义播放器”这篇文章吧。  ...
    99+
    2024-04-02
  • C语言如何实现音乐播放器
    本文小编为大家详细介绍“C语言如何实现音乐播放器”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现音乐播放器”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。实例代码如下:#include &l...
    99+
    2023-06-08
  • Android实现自定义轮播图片控件示例
    要完成一个轮播图片,首先想到的应该是使用ViewPager来实现。ViewPager已经有了滑动的功能,我们只要让它自己滚动。再加上下方的小圆点就行了。所以我们本次的自定义控件...
    99+
    2022-06-06
    轮播图 自定义 示例 图片 轮播 Android
  • Android实现自定义轮播图片控件详解
    首先上效果图 实现原理 要完成一个轮播图片,首先想到的应该是使用ViewPager来实现。ViewPager已经有了滑动的功能,我们只要让它自己滚动。再加上下方的小圆点就行了...
    99+
    2022-06-06
    轮播图 自定义 图片 轮播 Android
  • Android自定义控件实现UC浏览器语音搜索效果
     最近项目上要实现语音搜索功能,界面样式要模仿一下UC浏览器的样式,UC浏览器中有一个控件,会随着声音大小浮动,然后寻思偷个懒,百度一下,结果也没有找到类似的,只能自己动手了。先上图看我实现的效果:这是自定义控件的代码,里面注释也...
    99+
    2023-05-31
    android 语音 搜索
  • Android自定义控件实现优雅的广告轮播图
    前言 今天给大家带来一个新的控件–轮播图,网上已经有很多这类的博客来讲解如何实现的,那么我的这个有哪些特点呢?或是说有哪些不同呢? 满足了轮播图的基本要求,循环滑动,在最后一张...
    99+
    2022-06-06
    轮播图 广告 轮播 Android
  • 详解WPF中用户控件和自定义控件的使用
    目录介绍用户控件自定义控件按钮案例自定义控件中常用的知识点介绍 无论是在WPF中还是WinForm中,都有用户控件(UserControl)和自定义控件(CustomControl)...
    99+
    2023-03-02
    WPF用户控件 自定义控件 WPF用户控件 WPF 自定义控件 WPF 控件
  • C语言实现音乐播放器的示例代码
    目录介绍实现代码介绍 该程序是一个小的DEMO,实现了以下几个功能,可以借鉴学习。 功能1:鼠标选择互动功能。通过鼠标的移动和按下,按钮的颜色也会发生改变。 功能2:音乐的播放与暂停...
    99+
    2023-02-26
    C语言实现音乐播放器 C语言音乐播放器 C语言音乐播放
  • 怎么使用C语言实现音乐播放器
    本文小编为大家详细介绍“怎么使用C语言实现音乐播放器”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用C语言实现音乐播放器”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。介绍该程序是一个小的DEMO,实现了以...
    99+
    2023-07-05
  • C语言使用mciSendString实现播放音乐功能
    目录使用 mciSendString 播放音乐使用 mciSendCommand 播放音乐解决某些 MP3 无法播放的问题使用 PlaySound 函数播放音乐使用 mciSendS...
    99+
    2023-02-14
    C语言mciSendString播放音乐 C语言 播放音乐 C语言mciSendString
  • Android自定义UI实现微信语音
    本文实例为大家分享了java获取不同路径的方法,供大家参考,具体内容如下 思路: 自定义Button 获取DialogManager、AudioManager setOnLon...
    99+
    2022-06-06
    Android
  • 自定义WPF分页控件的全过程记录
    一、分页控件功能说明# 实现如上图所示的分页控件,需要实现一下几个功能: 可以设置每页能够展示的最大列数(例如每页8列、每页16列等等)。 加载的数组总数量超过...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作