基于WPF实现视频封面查看器

 更新时间:2022年11月30日 09:29:14   作者:驚鏵  
这篇文章主要为大家详细介绍了WPF如何实现视频封面查看器,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下

如何实现 WPF 视频封面查看器

  • 框架使用.NET40

  • Visual Studio 2019;
  • 实现视频封面查看器NineGridView基于Grid实现列,使用列做主封面展示视频播放(也可以做rtsp视频流播放),还剩下个做候选封面区展示,当点击封面区某个封面时进行替换主封面区视频(流)播放。
  • 当鼠标移动到候选封面区时,动画从上一次鼠标的位置到当前鼠标位置做移动动画。

示例代码

1)新建 NineGridView.cs 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace WPFDevelopers.Controls
{
    public class NineGridView : Grid
    {
        private int _rows = 3;

        private int _columns = 3;

        private Dictionary<Rect, int> _dicRect = new Dictionary<Rect, int>();

        private Border _border;

        private Storyboard _storyboard;

        private Rect _lastRect;

        private int _last;

        public static readonly DependencyProperty SelectBrushProperty =
          DependencyProperty.Register("SelectBrush", typeof(Brush), typeof(NineGridView),
              new PropertyMetadata(Brushes.Red));
        
        public static readonly DependencyProperty BorderThicknessProperty =
       DependencyProperty.Register("BorderThickness", typeof(Thickness), typeof(NineGridView),
           new PropertyMetadata(new Thickness(1)));

        public NineGridView()
        {
            Loaded += NineGridView_Loaded;
            SizeChanged += NineGridView_SizeChanged;
        }

        public Brush SelectBrush
        {
            get => (Brush)GetValue(SelectBrushProperty);
            set => SetValue(SelectBrushProperty, value);
        }
      
        public Thickness BorderThickness
        {
            get => (Thickness)GetValue(BorderThicknessProperty);
            set => SetValue(BorderThicknessProperty, value);
        }

        private void NineGridView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (_border == null || _last == 0) return;
            var frameworkElement = InternalChildren[_last] as FrameworkElement;
            if (frameworkElement == null) return;
            _border.Width = frameworkElement.ActualWidth;
            _border.Height = frameworkElement.ActualHeight;
            var point = frameworkElement.TranslatePoint(new Point(0, 0), this);
            CreateStoryboard(point);
        }
        private void NineGridView_Loaded(object sender, RoutedEventArgs e)
        {
            RowDefinitions.Clear();
            for (int i = 0; i < _rows; i++)
            {
                var row1 = new RowDefinition();
                RowDefinitions.Add(row1);
            }
            ColumnDefinitions.Clear();
            for (int i = 0; i < _columns; i++)
            {
                var col1 = new ColumnDefinition();
                ColumnDefinitions.Add(col1);
            }
            UIElementCollection children = InternalChildren;

            int numCol = 0, numRow = 0;
            for (int i = 0, count = children.Count; i < count; ++i)
            {
                if (i > 6) return;
                UIElement child = children[i];
                if (child != null)
                {
                    if (i == 0)
                    {
                        SetRowSpan(child, 2);
                        SetColumnSpan(child, 2);
                    }
                    else
                    {
                        var num = i - 1;
                        var col = GetColumnSpan(children[num]);
                        col = col == 1 ? GetColumn(children[num]) : col;
                        if (i + 1 <= _columns)
                        {
                            SetColumn(child, col);
                            SetRow(child, numRow);
                            numRow++;
                        }
                        else
                        {
                            var row = GetRowSpan(children[0]);
                            SetColumn(child, numCol);
                            SetRow(child, row);
                            numCol++;
                        }
                    }
                }
            }
            if(_border != null)
                Children.Remove(_border);
            _border = new Border
            {
                BorderThickness = BorderThickness,
                BorderBrush = SelectBrush,
                VerticalAlignment = VerticalAlignment.Top,
                HorizontalAlignment = HorizontalAlignment.Left
            };
            _border.Name = "PART_Adorner";
            _border.RenderTransform = new TranslateTransform();
            SetRowSpan(_border, _rows);
            SetColumnSpan(_border, _columns);
            _border.Width = ActualWidth / _columns - 2;
            _border.Height = ActualHeight / _rows - 2;
            var _translateTransform = (TranslateTransform)_border.RenderTransform;
            _translateTransform.X = _border.Width * 2 + 4;
            Children.Add(_border);
            _last = 1;
        }

        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            base.OnPreviewMouseMove(e);
            var currentPoint = e.GetPosition(this);
            if (_lastRect.Contains(currentPoint))
                return;
            _dicRect.Clear();
            UIElementCollection children = InternalChildren;
            for (int i = 0, count = children.Count; i < count; ++i)
            {
                if (i >= 6 || i == 0) continue;
                var child = children[i] as FrameworkElement;
                if (child != null)
                {
                    var point = child.TranslatePoint(new Point(0, 0), this);
                    var rect = new Rect(point.X, point.Y, child.ActualWidth, child.ActualHeight);
                    _dicRect.Add(rect, i);
                }
            }


            var model = _dicRect.Keys.FirstOrDefault(x => x.Contains(currentPoint));
            if (model == default) return;
            _dicRect.TryGetValue(model, out _last);
            if (_border == null) return;

            CreateStoryboard(new Point(model.X, model.Y));
            _border.Width = model.Width;
            _border.Height = model.Height;
            _lastRect = model;
        }
        void CreateStoryboard(Point point)
        {
            var sineEase = new SineEase() { EasingMode = EasingMode.EaseOut };
            if (_storyboard == null)
                _storyboard = new Storyboard();
            else
                _storyboard.Children.Clear();
            var animationX = new DoubleAnimation
            {
                Duration = TimeSpan.FromMilliseconds(500),
                To = point.X,
                EasingFunction = sineEase
            };
            Storyboard.SetTargetProperty(animationX, new PropertyPath("(Border.RenderTransform).(TranslateTransform.X)"));
            _storyboard.Children.Add(animationX);
            var animationY = new DoubleAnimation
            {
                Duration = TimeSpan.FromMilliseconds(500),
                To = point.Y,
                EasingFunction = sineEase
            };
            Storyboard.SetTargetProperty(animationY, new PropertyPath("(Border.RenderTransform).(TranslateTransform.Y)"));
            _storyboard.Children.Add(animationY);
            _storyboard.Begin(_border);

        }
    }
}

2)新建 NineGridViewExample.xaml 代码如下:

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.NineGridViewExample"
             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:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
              xmlns:controls="clr-namespace:WPFDevelopers.Samples.Controls"
             xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <controls:CodeViewer>
        <wpfdev:NineGridView BorderThickness="1" SelectBrush="Red">
            <wpfdev:NineGridView.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="Foreground" Value="White"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="HorizontalAlignment" Value="Center"/>
                </Style>
                <Style TargetType="Border">
                    <Setter Property="Margin" Value="1"/>
                </Style>
            </wpfdev:NineGridView.Resources>
            <MediaElement x:Name="MyMediaElement" Loaded="MyMediaElement_Loaded"
                          MediaEnded="MyMediaElement_MediaEnded"/>
            <Border Background="#282C34">
                <wpfdev:SmallPanel>
                    <TextBlock Text="信号源1"/>
                    <Border Background="{DynamicResource PrimaryNormalSolidColorBrush}"
                            VerticalAlignment="Top"
                            HorizontalAlignment="Right"
                            Padding="10,4"
                            CornerRadius="3">
                        <TextBlock Text="HD"/>
                    </Border>
                </wpfdev:SmallPanel>
            </Border>
            <Border Background="#282C34">
                <TextBlock Text="无信号"/>
            </Border>
            <Border Background="#282C34">
                <TextBlock Text="无信号"/>
            </Border>
            <Border Background="#282C34">
                <TextBlock Text="无信号"/>
            </Border>
            <Border Background="#282C34">
                <TextBlock Text="无信号"/>
            </Border>
        </wpfdev:NineGridView>
        <controls:CodeViewer.SourceCodes>
            <controls:SourceCodeModel 
                CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/NineGridViewExample.xaml" 
                CodeType="Xaml"/>
            <controls:SourceCodeModel 
                CodeSource="/WPFDevelopers.SamplesCode;component/ExampleViews/NineGridViewExample.xaml.cs" 
                CodeType="CSharp"/>
        </controls:CodeViewer.SourceCodes>
    </controls:CodeViewer>
</UserControl>

3)新建 NineGridViewExample.xaml.cs 代码如下:

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;

namespace WPFDevelopers.Samples.ExampleViews
{
    /// <summary>
    /// NineGridViewExample.xaml 的交互逻辑
    /// </summary>
    public partial class NineGridViewExample : UserControl
    {
        public NineGridViewExample()
        {
            InitializeComponent();
        }

        private void MyMediaElement_Loaded(object sender, RoutedEventArgs e)
        {
            var path = "E:\\DCLI6K5UIAEmH9R.mp4";
            if (File.Exists(path))
                MyMediaElement.Source = new Uri("path");
        }

        private void MyMediaElement_MediaEnded(object sender, RoutedEventArgs e)
        {
            MyMediaElement.Position = new TimeSpan(0);
        }
        
    }
}

效果图

到此这篇关于基于WPF实现视频封面查看器的文章就介绍到这了,更多相关WPF视频封面查看器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#下listview如何插入图片

    C#下listview如何插入图片

    这篇文章主要为大家详细介绍了C#下listview如何插入图片,如何在listview中插入图片的每一个步骤为大家分享,感兴趣的朋友可以参考一下
    2016-05-05
  • C#实现获取文件大小并进行比较

    C#实现获取文件大小并进行比较

    这篇文章主要为大家详细介绍了C#如何实现获取文件大小进行单位转换与文件大小比较功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-03-03
  • C#弹出对话框确定或者取消执行相应操作的实例代码

    C#弹出对话框确定或者取消执行相应操作的实例代码

    这篇文章主要介绍了C#弹出对话框确定或者取消执行相应操作的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • WPF利用DrawingContext实现绘制温度计

    WPF利用DrawingContext实现绘制温度计

    这篇文章主要为大家详细介绍了如何利用WPF和DrawingContext实现绘制温度计,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
    2022-09-09
  • C#实现Excel动态生成PivotTable

    C#实现Excel动态生成PivotTable

    这篇文章主要为大家详细介绍了C#实现Excel动态生成PivotTable的相关方法,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • 基于XSLT调试的相关问题

    基于XSLT调试的相关问题

    本篇文章是对XSLT调试的相关问题进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C#多种操作excel的方法比较

    C#多种操作excel的方法比较

    本文详细讲解了C#多种操作excel的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C#代码操作XML进行增、删、改操作

    C#代码操作XML进行增、删、改操作

    这篇文章主要为大家详细介绍了C# 代码操作XML进行增、删、改操作,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • 轻松学习C#的预定义数据类型

    轻松学习C#的预定义数据类型

    轻松学习C#的预定义数据类型,C#的预定义数据类型包括两种,一种是值类型,一种是引用类型,需要的朋友可以参考下
    2015-11-11
  • c#中合并excel表格的方法示例

    c#中合并excel表格的方法示例

    本篇文章主要介绍了c#中合并excel表格的方法,就是将excel表格结构一样的合并到一起,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2016-10-10

最新评论