源项目地址:https://github.com/Microsoft/...
以下是把样例转换为简要说明,同时给出实际运行效果及关键代码剖析:
VideoViewerDemo视频播放器示例
实现效果:
- 根据目录名选择里面播放文件,添加到列表。
- 点击播放列表,播放区自动播放对应文件
- 在播放列表上的鼠标提示中播放文件(无声的)
关注词:
- DirectoryInfo+ObservableCollection运用
- 数据绑定运用
- tooltip模板应用
实现步骤:
创建数据类MyVideo,包含标题及文件Uri.接收完整目录字符串及文件名
视频集类MyVideos
public class MyVideos : ObservableCollection<MyVideo>
存储指定路径目录及转换数据类对象添加,每次访问新目录时,如目录存在且有文件,就进行更新把文件添加到集中
public string Directory
{
set
{
// Don't set path if directory is invalid
if (!System.IO.Directory.Exists(value))
{
MessageBox.Show("No Such Directory");
}
_directory = new DirectoryInfo(value);
Update();
}
get { return _directory.FullName; }
}
private void Update()
{
// Don't update if no directory to get files from
if (_directory == null) return;
// Remove all MyVideo objects from this collection
Clear();
// Create MyVideo objects
foreach (var f in _directory.GetFiles("*.wmv"))
{
Add(new MyVideo(f.FullName, f.Name));
}
}
Window窗口资源
实例化一个视频集类
<local:MyVideos Directory="../../media" x:Key="Vids" />
主屏幕播放区的数据模板,在grid后面垫有默认图片,没有播放时显示出来。
Souce绑定数据类的Uri属性
<DataTemplate x:Key="MainScreenTemplate">
<Border BorderBrush="LimeGreen" BorderThickness="2"
CornerRadius="3" Margin="15">
<Grid>
<!-- Background image if no video is playing. -->
<Image Source="Images\Crystal.jpg" Stretch="Fill" />
<!-- The video -->
<!-- The Source property of the video is bound to the Source property of the current MyVideo object.-->
<MediaElement Name="mainVideo" Stretch="Fill"
Source="{Binding Path=Source}" />
</Grid>
</Border>
</DataTemplate>
列表工具提示作为资源,模板中设置声音被禁止。
X:Shared用于指定请求资源时创建实例的两种方式。
X:Shared = “true”(默认):表示所有请求都是共享同一个实例。一般不显示指定。
X:Shared = “false”:表示每次请求都创建一个新的实例。
<!-- Must be placed above listBoxTemplate -->
<ToolTip x:Key="PreviewScreen" x:Shared="True" Background="Transparent"
Placement="Right" Name="previewToolTip">
<Border BorderBrush="RoyalBlue" BorderThickness="2" CornerRadius="2">
<MediaElement Source="{Binding Path=Source}"
Opacity="0.8" IsMuted="True" />
</Border>
</ToolTip>
列表子项显示的数据模板,其中的资源对Dock容器样式进行设置,样式中鼠标悬浮触发显示上面的工具提示控件
<DataTemplate x:Key="ListBoxTemplate">
<DataTemplate.Resources>
<Style TargetType="DockPanel">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="ToolTipService.ShowDuration" Value="80000" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ToolTip" Value="{StaticResource PreviewScreen}" />
</Trigger>
</Style.Triggers>
</Style>
</DataTemplate.Resources>
<DockPanel Height="70" Width="160">
<Border Margin="4,5,0,0" Height="50" Width="50">
<Image Source="Images\Preview.png" />
</Border>
<TextBlock Text="{Binding Path=VideoTitle}" VerticalAlignment="Center"
TextBlock.TextTrimming="CharacterEllipsis" Margin="5,5,0,5"
Foreground="Black" FontSize="12" FontFamily="Comic Sans MS" />
</DockPanel>
</DataTemplate>
对每个列表子项显示的样式资源,其的每个子项的内容模板进行了修饰,两个方框进行鼠标进入及退出时背景色变化动画触发。每个子项的样式又进行鼠标选中时的方框背景色变化动画触发。
<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
<Setter Property="Margin" Value="10,10,10,0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid>
<Rectangle x:Name="GelBackground" RadiusX="9" RadiusY="9"
Opacity="1" Fill="{TemplateBinding Background}"
Stroke="#66ffffff" StrokeThickness="1" />
<Rectangle x:Name="GelShine" RadiusX="6" RadiusY="6"
Opacity="1" Margin="2,2,2,0" VerticalAlignment="top"
Stroke="transparent" Height="15">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#ccffffff" Offset="0" />
<GradientStop Color="transparent" Offset="1" />
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation To="LimeGreen" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="GelBackground"
TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<ColorAnimation Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="RoyalBlue" />
</Trigger>
</Style.Triggers>
</Style>
- 前台播放列表及播放器xaml代码
其中IsSynchronizedWithCurrentItem="True"必须设置,意思为同步当前选择项进行处理。就是当选中一个播放项,同一个绑定源的控件ContentControl实例化选中的视频自动到MediaElement进行播放,可谓关键代码。
<!-- 1) The ListBox and ContentControl bind to the same source. -->
<!-- 2) IsSynchronizedWithCurrentItem set to true. -->
<!-- With the above 2 conditions satisfied, once the DataTemplates are in place, the ContentControl will display the content of the selected list item.-->
<DockPanel>
<ListBox DockPanel.Dock="Left" Width="200" BorderThickness="0"
ItemsSource="{Binding Source={StaticResource Vids}}"
IsSynchronizedWithCurrentItem="True"
ItemTemplate="{StaticResource ListBoxTemplate}"
Background="Transparent" />
<ContentControl Content="{Binding Source={StaticResource Vids}}"
ContentTemplate="{StaticResource MainScreenTemplate}" />
</DockPanel>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。