基于WPF實現(xiàn)視頻封面查看器
如何實現(xiàn) WPF 視頻封面查看器
框架使用
.NET40;Visual Studio 2019;- 實現(xiàn)視頻封面查看器
NineGridView基于Grid實現(xiàn)三行三列,使用兩行兩列做主封面展示視頻播放(也可以做rtsp視頻流播放),還剩下五個做候選封面區(qū)展示,當點擊封面區(qū)某個封面時進行替換主封面區(qū)視頻(流)播放。 - 當鼠標移動到候選封面區(qū)時,動畫從上一次鼠標的位置到當前鼠標位置做移動動畫。

示例代碼
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);
????????}
????????
????}
}
效果圖

到此這篇關(guān)于基于WPF實現(xiàn)視頻封面查看器的文章就介紹到這了,更多相關(guān)WPF視頻封面查看器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#利用Openxml讀取Excel數(shù)據(jù)實例
這篇文章主要介紹了C#利用Openxml讀取Excel數(shù)據(jù)的方法,包括使用中的注意點分析及疑難探討,需要的朋友可以參考下2014-09-09
C#基礎(chǔ)教程之類class與結(jié)構(gòu)struct的區(qū)別
struct是值類型,創(chuàng)建一個struct類型的實例被分配在棧上,class是引用類型,創(chuàng)建一個class類型實例被分配在托管堆上,下面這篇文章主要給大家介紹了關(guān)于C#基礎(chǔ)教程之類class與結(jié)構(gòu)struct區(qū)別的相關(guān)資料,需要的朋友可以參考下2022-11-11
C#中IEnumerator<T>和IEnumerable的區(qū)別
在C#中,IEnumerator<T>和IEnumerable是用于實現(xiàn)迭代的接口,本文主要介紹了C#中IEnumerator<T>和IEnumerable的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-01-01

