逐步解說:使用 WPF 設計工具建立視訊瀏覽器
本逐步解說會示範如何使用 WPF Designer for Visual Studio 建立 WPF 應用程式來瀏覽視訊檔案。
在這個逐步解說中,您會執行下列工作:
建立專案。
建立配置。
將控制項加入至配置。
設定與配置相關的屬性。
建立資料來源類型。
建立 WPF 控制項。
在應用程式中使用控制項。
實作應用程式邏輯。
啟用資料繫結。
設定應用程式樣式。
下圖顯示應用程式的顯示方式。
完成時,您就會有一個應用程式可讓您瀏覽資料夾中的 Windows Media Player (WMV) 檔案。 每個 .wmv 檔案都必須有同名的對應 .jpg 檔案。 例如,bear.wmv 在相同資料夾中必須有 bear.jpg。
注意事項 |
---|
根據您目前使用的設定或版本,您所看到的對話方塊與功能表指令可能會與 [說明] 中描述的不同。 若要變更設定,請從 [工具] 功能表中選取 [匯入和匯出設定]。 如需詳細資訊,請參閱 使用設定。 |
注意事項 |
---|
以下內容已獲得 Application Developers Training Company (也就是這段原始程式碼/範例的擁有者與建立者) 的複製授權。 原始用法顯示在教學軟體 "Developing Applications for Visual Studio 2008" (作者 Ken Getz,Copyright 2007 Application Developers Training Company) 中。 如需詳細資訊,請參閱 http://www.appdev.com (英文)。 |
必要條件
您需要下列元件才能完成此逐步解說:
- Visual Studio 2010。
建立專案
第一步是建立主應用程式的專案。 MoviePlayerControl 是一個 UserControl,其中包含 MediaElement 和操作視訊播放的其他控制項。
若要建立專案
建立名為 VideoBrowser 的 WPF 應用程式專案。 如需詳細資訊,請參閱 HOW TO:建立新的 WPF 應用程式專案。
MainWindow.xaml 隨即在 WPF 設計工具中開啟。
將新的 WPF 使用者控制項程式庫專案加入到方案中。 將專案命名為 MoviePlayerControlLibrary。 如需詳細資訊,請參閱 HOW TO:建立 WPF UserControl 程式庫專案。
在 MoviePlayerControlLibrary 專案中,加入名為 MoviePlayerControl 的新 WPF 使用者控制項。 如需詳細資訊,請參閱 HOW TO:加入新項目至 WPF 專案。
從專案刪除 UserControl1。
建立配置
配置會定義控制項在應用程式的主視窗中如何排列。 下列步驟示範如何建構配置項目,其中包含應用程式的控制項。
若要建立配置
在 WPF 設計工具中開啟 MediaPlayerControl.xaml。
選取使用者控制項上的根 Grid 控制項。 如需詳細資訊,請參閱HOW TO:在設計介面上選取並移動項目。
在 [屬性] 視窗中,將根 Grid 控制項的名稱設定為 moviePlayerGrid。 Name 屬性是在 [屬性] 視窗的頂端設定。
再將兩個資料列加入到 moviePlayerGrid。 如需詳細資訊,請參閱 HOW TO:在方格中加入資料列和資料行。
在 [文件大綱] 視窗中,選取 moviePlayerGrid 中的第一個資料列,並將其 MinHeight 屬性設定為 50。
選取 moviePlayerGrid 中的第二個資料列,並將其 Height 設定為 20。
選取 moviePlayerGrid 中的第三個資料列,並將其 Height 設定為 55。
從 [工具箱] 中,將 Grid 控制項拖曳到 moviePlayerGrid 的第三個資料列。
WPF 設計工具會建立名為 grid1 的新 Grid 控制項。
在 [屬性] 視窗中,將 grid1 的名稱設定為 mediaControlsGrid。
將 mediaControlsGrid 的 Margin 屬性設定為 0。
在 [屬性] 視窗中,開啟 ColumnDefinitions 集合編輯器,然後加入五個資料行定義。
從 [工具箱] 中,將 StackPanel 控制項拖曳到 mediaControlsGrid 的最後一個資料行。
WPF 設計工具會建立名為 stackPanel1 的新 StackPanel 控制項。
開啟 [文件大綱] 視窗來確認配置。 如需詳細資訊,請參閱巡覽 WPF 文件的項目階層架構。
確定物件階層架構顯示如下:
Grid (moviePlayerGrid)
RowDefinitions
Grid (mediaControlsGrid)
ColumnDefinitions
StackPanel (stackPanel1)
如果物件階層架構並未遵循此模式,請拖曳物件或修改 XAML,直到顯示上面的階層架構。
將控制項加入至配置
定義了配置後,您可以使用控制項填入配置。 在 [工具箱] 中,按一下您要的控制項,然後將控制項拖曳至設計介面。
若要將控制項加入至配置
從 [工具箱] 中,將 MediaElement 控制項拖曳到 moviePlayerGrid 的第一個資料列。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
moviePlayer
Margin
0
Width
Auto
Height
Auto
HorizontalAlignment
Stretch
VerticalAlignment
Stretch
LoadedBehavior
Manual
從 [工具箱] 中,將 Button 控制項拖曳到 mediaControlsGrid 的第一個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
backButton
Content
Back
Margin
0
從 [工具箱] 中,將 Button 控制項拖曳到 mediaControlsGrid 的第二個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
playButton
Content
Play
Margin
0
從 [工具箱] 中,將 Button 控制項拖曳到 mediaControlsGrid 的第三個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
stopButton
Content
Stop
Margin
0
從 [工具箱] 中,將 Button 控制項拖曳到 mediaControlsGrid 的第四個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
forwardButton
Content
Fwd
Margin
0
從 [工具箱] 中,將 TextBlock 控制項拖曳到 mediaControlsGrid 的第五個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Text
Volume
Width
Auto
Height
Auto
HorizontalAlignment
Center
VerticalAlignment
Stretch
從 [工具箱] 中,將 Slider 控制項拖曳到 mediaControlsGrid 的第五個資料行。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
volumeSlider
Width
Auto
Height
Auto
Minimum
0
Maximum
1
Margin
5
從 [工具箱] 中,將 Slider 控制項拖曳到 moviePlayerGrid 的第二個資料列。
在 [屬性] 視窗中,設定下列屬性,如下所示。
屬性
值
Name
positionSlider
Width
Auto
Height
Auto
Minimum
0
Maximum
1
Margin
2
HorizontalAlignment
Stretch
VerticalAlignment
Stretch
加入事件處理常式
您的應用程式會藉由處理事件來回應使用者輸入。 下列程序顯示如何為 MoviePlayerControl 中的控制項引發的事件加入事件處理常式。 如需詳細資訊,請參閱 HOW TO:建立簡單的事件處理常式。
若要加入事件處理常式
在 [XAML] 檢視中,將游標放在 <MediaElement> 標記內,然後輸入 MediaOpened=。
Intellisense 會顯示 [<新事件處理常式>] 選項。
選取 [<新事件處理常式>]。
WPF 設計工具會在程式碼檔案中建立 moviePlayer_MediaOpened 事件處理常式。
針對 MediaEnded 事件重複步驟 1 和 2。
在 [設計] 檢視中,按兩下 positionSlider。
WPF 設計工具會在程式碼檔案中建立 positionSlider_ValueChanged 事件處理常式。
在 [設計] 檢視中,按兩下 backButton。
WPF 設計工具會在程式碼檔案中建立 backButton_Click 事件處理常式。
按兩下其餘的按鈕控制項,為每個控制項產生 Click 事件處理常式。
按兩下 positionSlider,以產生 ValueChanged 事件處理常式。
實作 MoviePlayerControl 的邏輯
在名為 MoviePlayerControl.xaml.cs 或 MoviePlayerControl.xaml.vb 的程式碼檔案中實作 MoviePlayerControl 的邏輯。
若要實作 MoviePlayerControl 的邏輯
在 [方案總管] 中,按兩下 MoviePlayerControl.xaml.cs 或 MoviePlayerControl.xaml.vb,在 [程式碼編輯器] 中開啟程式碼檔案。
將下列程式碼插入到 MoviePlayerControl 類別定義中,建構函式前面的位置。
' Specifies whether the movie is playing. Private playing As Boolean ' Used to update the position slider's current value. Private timer As New System.Windows.Threading.DispatcherTimer()
// Specifies whether the movie is playing. private bool playing; // Used to update the position slider's current value. private System.Windows.Threading.DispatcherTimer timer = new System.Windows.Threading.DispatcherTimer();
將下列程式碼插入到 MoviePlayerControl 類別定義中,事件處理常式定義後面的位置。
#Region "Utility Methods" Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs) ' The DispatcherTimer's Tick event handler runs ' in the UI thread, so you can work with the UI ' without worrying about cross-thread issues. positionSlider.Value = moviePlayer.Position.TotalMilliseconds End Sub Private Sub PlayMovie() If Not playing Then ' The Play method will begin the media if it is not currently active or ' resume media if it is paused. This has no effect if the media is ' already running. moviePlayer.Play() playButton.Content = "Pause" playing = True Else moviePlayer.Pause() playButton.Content = "Play" playing = False End If End Sub Private Sub StopMovie() ' The Stop method stops and resets the media to be played from ' the beginning. moviePlayer.Stop() moviePlayer.Position = TimeSpan.Zero playButton.Content = "Play" playing = False End Sub #End Region
#region Utility Methods void timer_Tick(object sender, EventArgs e) { // The DispatcherTimer's Tick event handler runs // in the UI thread, so you can work with the UI // without worrying about cross-thread issues. positionSlider.Value = moviePlayer.Position.TotalMilliseconds; } private void PlayMovie() { if (!playing) { // The Play method will begin the media if it is not currently active or // resume media if it is paused. This has no effect if the media is // already running. moviePlayer.Play(); playButton.Content = "Pause"; playing = true; } else { moviePlayer.Pause(); playButton.Content = "Play"; playing = false; } } private void StopMovie() { // The Stop method stops and resets the media to be played from // the beginning. moviePlayer.Stop(); moviePlayer.Position = TimeSpan.Zero; playButton.Content = "Play"; playing = false; } #endregion
將自動產生的事件處理常式替換成下列程式碼。
Private Sub moviePlayer_MediaOpened(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Put code here that runs when the media ' is first opened. ' Set the media's starting Volume to the current ' value of the slider control. moviePlayer.Volume = System.Convert.ToDouble(volumeSlider.Value) positionSlider.Maximum = moviePlayer.NaturalDuration.TimeSpan.TotalMilliseconds ' Update the position slider every second. timer.Interval = New TimeSpan(0, 0, 1) timer.Start() End Sub Private Sub moviePlayer_MediaEnded(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Media playback is finished. ' Stop the media to seek to media start. StopMovie() timer.Stop() End Sub Private Sub positionSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double)) ' Create a TimeSpan with milliseconds equal to the slider value. Dim ts As New TimeSpan(0, 0, 0, 0, Fix(positionSlider.Value)) moviePlayer.Position = ts ' Jump back 5 seconds: moviePlayer.Position = moviePlayer.Position.Subtract(New TimeSpan(0, 0, 0, 0, 5000)) positionSlider.Value = moviePlayer.Position.TotalMilliseconds End Sub Private Sub backButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Jump back 5 seconds: moviePlayer.Position = _ moviePlayer.Position.Subtract(New TimeSpan(0, 0, 0, 0, 5000)) positionSlider.Value = _ moviePlayer.Position.TotalMilliseconds End Sub Private Sub playButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) PlayMovie() End Sub Private Sub stopButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) StopMovie() End Sub Private Sub forwardButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) ' Jump ahead 5 seconds: moviePlayer.Position = moviePlayer.Position.Add(New TimeSpan(0, 0, 0, 0, 5000)) positionSlider.Value = moviePlayer.Position.TotalMilliseconds End Sub Private Sub volumeSlider_ValueChanged(ByVal sender As Object, ByVal e As RoutedPropertyChangedEventArgs(Of Double)) moviePlayer.Volume = System.Convert.ToDouble(volumeSlider.Value) End Sub
private void moviePlayer_MediaOpened(object sender, RoutedEventArgs e) { // Put code here that runs when the media // is first opened. // Set the media's starting Volume to the current // value of the slider control. moviePlayer.Volume = (double)volumeSlider.Value; positionSlider.Maximum = moviePlayer.NaturalDuration.TimeSpan.TotalMilliseconds; // Update the position slider every second. timer.Interval = new TimeSpan(0, 0, 1); timer.Start(); } private void moviePlayer_MediaEnded(object sender, RoutedEventArgs e) { // Media playback is finished. // Stop the media to seek to media start. StopMovie(); timer.Stop(); } private void positionSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { // Create a TimeSpan with milliseconds equal to the slider value. TimeSpan ts = new TimeSpan( 0, 0, 0, 0, (int)positionSlider.Value); moviePlayer.Position = ts; } private void backButton_Click(object sender, RoutedEventArgs e) { // Jump back 5 seconds: moviePlayer.Position = moviePlayer.Position.Subtract(new TimeSpan(0, 0, 0, 0, 5000)); positionSlider.Value = moviePlayer.Position.TotalMilliseconds; } private void playButton_Click(object sender, RoutedEventArgs e) { PlayMovie(); } private void stopButton_Click(object sender, RoutedEventArgs e) { StopMovie(); } private void forwardButton_Click(object sender, RoutedEventArgs e) { // Jump ahead 5 seconds: moviePlayer.Position = moviePlayer.Position.Add(new TimeSpan(0, 0, 0, 0, 5000)); positionSlider.Value = moviePlayer.Position.TotalMilliseconds; } private void volumeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { moviePlayer.Volume = (double)volumeSlider.Value; }
將自動產生的建構函式替換成下列程式碼。
Public Sub New() InitializeComponent() ' Initialize the timer's Tick event handler: AddHandler timer.Tick, AddressOf timer_Tick End Sub
public MoviePlayerControl() { InitializeComponent(); // Initialize the timer's Tick event handler: timer.Tick += new EventHandler(timer_Tick); }
插入下列方法來定義控制項的公用介面。
Public Sub PlayMovie(ByVal movie As Uri) moviePlayer.Source = movie PlayMovie() End Sub Public Sub Close() StopMovie() moviePlayer.Close() End Sub
public void PlayMovie(Uri movie) { moviePlayer.Source = movie; PlayMovie(); } public void Close() { StopMovie(); moviePlayer.Close(); }
按 F6 建置控制項。
建立資料來源類型
您可以使用資料繫結,將控制項連接至資料。 在這個應用程式中,視訊瀏覽器的 ListBox 控制項會繫結至名為 ThumbnailList 的自訂類別。
若要建立資料來源類型
將名為 ThumbnailList 的新類別加入到 VideoBrowser 專案。
在 [程式碼編輯器] 中開啟 ThumbnailList.cs 或 ThumbnailList.vb,然後將自動產生的程式碼替換成下列程式碼。
Imports System Imports System.Collections.Generic Imports System.Text Imports System.IO Imports System.Collections.ObjectModel Imports System.ComponentModel Imports System.Windows.Media.Imaging Imports System.Collections.Specialized Imports System.Windows.Controls Public Class ThumbnailList Inherits ObservableCollection(Of String) ' Can't set the path in the constructor, ' because the main form uses static binding to ' bind to an instance of this class, which gets ' created before the form (and therefore, before ' you've specified a folder). If you create a new ' instance of this class when you supply the path ' name, the static binding is now binding to the original ' (empty) collection. Therefore, this code must ' allow you to modify the folder for the existing ' instance of this class. Private _folderName As String ' Public Property FolderName() As String Get Return _folderName End Get Set _folderName = value ' Now fill in the collection of ' file names: Me.Clear() Dim fileName As String For Each fileName In Directory.GetFiles(Me.FolderName, "*.jpg") Me.Add(fileName) Next fileName End Set End Property End Class
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Collections.ObjectModel; using System.ComponentModel; using System.Windows.Media.Imaging; using System.Collections.Specialized; using System.Windows.Controls; namespace VideoBrowser { public class ThumbnailList : ObservableCollection<String> { // Can't set the path in the constructor, // because the main form uses static binding to // bind to an instance of this class, which gets // created before the form (and therefore, before // you've specified a folder). If you create a new // instance of this class when you supply the path // name, the static binding is now binding to the original // (empty) collection. Therefore, this code must // allow you to modify the folder for the existing // instance of this class. String _folderName; public string FolderName { get { return _folderName; } set { _folderName = value; // Now fill in the collection of // file names: this.Clear(); foreach (string fileName in Directory.GetFiles(this.FolderName, "*.jpg")) { this.Add(fileName); } } } } }
將名為 FileToURIConverter 的新類別加入到 VideoBrowser 專案。
在 [程式碼編輯器] 中開啟 FileToURIConverter.cs 或 FileToURIConverter.vb,然後將自動產生的程式碼替換成下列程式碼。
Imports System Imports System.Collections.Generic Imports System.Linq Imports System.Text Imports System.Windows.Data Imports System.Windows.Media.Imaging Namespace VideoBrowser Class FileToURIConverter Implements IValueConverter Public Function Convert( _ ByVal value As Object, _ ByVal targetType As Type, _ ByVal parameter As Object, _ ByVal culture As System.Globalization.CultureInfo) As Object _ Implements IValueConverter.Convert ' In design mode, value is not a string, so it is ' important to check input parameters. If CType(value, String) IsNot Nothing Then ' Convert from the image name to a BitmapFrame ' for display in the list. Return BitmapFrame.Create(New Uri(value.ToString())) Else Return Nothing End If End Function Public Function ConvertBack( _ ByVal value As Object, _ ByVal targetType As Type, _ ByVal parameter As Object, _ ByVal culture As System.Globalization.CultureInfo) As Object _ Implements IValueConverter.ConvertBack Throw New NotImplementedException() End Function End Class End Namespace
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Data; using System.Windows.Media.Imaging; using System.ComponentModel; namespace VideoBrowser { class FileToURIConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // In design mode, value is not a string, so it is // important to check input parameters. if (value is string) { // Convert from the image name to a BitmapFrame // for display in the list. return BitmapFrame.Create(new Uri(value.ToString())); } else { return null; } } public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } } }
儲存所有檔案。
在應用程式中使用控制項
建立控制項之後,就可以將它用於應用程式。
若要使用 WPF 控制項
在 [方案總管] 的 VideoBrowser 專案中,加入 MoviePlayerControlLibrary 專案的參考。 如需詳細資訊,請參閱專案參考。
加入 System.Windows.Forms 組件的參考。 FolderBrowserDialog 需要這項參考。
在 [XAML] 檢視中開啟 MainWindow.xaml,然後將自動產生的程式碼替換成下列程式碼。
<Window x:Class="VideoBrowser.MainWindow" Name="window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:media = "clr-namespace:MoviePlayerControlLibrary;assembly=MoviePlayerControlLibrary" xmlns:vb="clr-namespace:VideoBrowser" Title="Video Browser" Height="540" Width="383"> <Window.Resources> <vb:FileToURIConverter x:Key="myConverter" /> <DataTemplate x:Key="imageTemplate"> <Border VerticalAlignment="Center" HorizontalAlignment="Center" Padding="4" Margin="2" Background="White"> <Image Source="{Binding Converter={StaticResource myConverter}}" /> </Border> </DataTemplate> <!--<ResourceDictionary > <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources.xaml"/> </ResourceDictionary.MergedDictionaries> <vb:FileToURIConverter x:Key="myConverter" /> <DataTemplate x:Key="imageTemplate"> <Border VerticalAlignment="Center" HorizontalAlignment="Center" Padding="4" Margin="2" Background="White"> <Image Source="{Binding Converter={StaticResource myConverter}}" /> </Border> </DataTemplate> </ResourceDictionary>--> </Window.Resources> <Grid Name="grid1"> <Grid.RowDefinitions> <RowDefinition Height="125" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Grid Margin="0" Name="grid2"> <Grid.ColumnDefinitions> <ColumnDefinition Width="115" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Button x:Name="selectFolderButton" Click="selectFolderButton_Click">Select folder...</Button> <ListBox Grid.Column="1" Margin="0,0,0,0" Name="videoListBox" SelectionChanged ="videoListBox_SelectionChanged" ItemTemplate="{StaticResource imageTemplate}" ItemsSource="{Binding ElementName=window1, Path=Thumbnails}" /> </Grid> <media:MoviePlayerControl x:Name="moviePlayer" Grid.Row="1" /> </Grid> </Window>
在 [程式碼編輯器] 中開啟名為 MainWindow.xaml.cs 或 MainWindow.xaml.vb 的程式碼檔案,然後將自動產生的程式碼替換成下列程式碼。
Imports System Imports System.Windows Imports System.Windows.Controls Imports System.Windows.Documents Imports System.Windows.Navigation Imports System.Windows.Shapes Imports System.Windows.Data Imports System.Windows.Media Imports System.Windows.Input Imports wfs = System.Windows.Forms Imports Microsoft.Win32 Namespace VideoBrowser Class MainWindow Inherits Window Public Sub New() InitializeComponent() End Sub ' The list box on the form is ' bound to this variable. Private _thumbnails As New ThumbnailList() Public Property Thumbnails() As ThumbnailList Get Return _thumbnails End Get Set(ByVal value As ThumbnailList) _thumbnails = value End Set End Property Private Sub videoListBox_SelectionChanged( _ ByVal sender As Object, _ ByVal e As SelectionChangedEventArgs) moviePlayer.Close() ' Get the image name: Dim imageName As String = videoListBox.SelectedItem.ToString() ' Find the associated movie: Dim movieName As String = System.IO.Path.ChangeExtension(imageName, "wmv") ' Create a new URI for the selected movie, and play it: moviePlayer.PlayMovie(New Uri(movieName)) End Sub Private Sub selectFolderButton_Click( _ ByVal sender As Object, _ ByVal e As RoutedEventArgs) Dim folderBrowser = New wfs.FolderBrowserDialog() folderBrowser.RootFolder = Environment.SpecialFolder.MyComputer If folderBrowser.ShowDialog() = wfs.DialogResult.OK Then Thumbnails.FolderName = folderBrowser.SelectedPath End If End Sub End Class End Namespace
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Data; using System.Windows.Media; using System.Windows.Input; using wfs = System.Windows.Forms; using Microsoft.Win32; namespace VideoBrowser { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } // The list box on the form is // bound to this variable. private ThumbnailList _thumbnails = new ThumbnailList(); public ThumbnailList Thumbnails { get { return _thumbnails; } set { _thumbnails = value; } } private void videoListBox_SelectionChanged( object sender, SelectionChangedEventArgs e) { moviePlayer.Close(); // Get the image name: String imageName = videoListBox.SelectedItem.ToString(); // Find the associated movie: string movieName = System.IO.Path. ChangeExtension(imageName, "wmv"); // Create a new URI for the selected movie, and play it: moviePlayer.PlayMovie(new Uri(movieName)); } private void selectFolderButton_Click(object sender, RoutedEventArgs e) { var folderBrowser = new wfs.FolderBrowserDialog(); folderBrowser.RootFolder = Environment.SpecialFolder.MyComputer; if (folderBrowser.ShowDialog() == wfs.DialogResult.OK) { Thumbnails.FolderName = folderBrowser.SelectedPath; } } } }
檢查點
您現在可以建置並執行應用程式; 按 [選取資料夾] 按鈕,然後巡覽至包含 .wmv 和對應 .jpg 檔案的資料夾。 選取好資料夾之後,.jpg 縮圖就會顯示在清單方塊中。 按一下其中一個縮圖,對應的 .wmv 檔案即會開始在 MediaElement 中播放。
設定應用程式樣式
VideoBrowser 應用程式會使用預設樣式呈現。 您可以建立和套用樣式來變更應用程式的外觀和行為。 樣式通常會儲存在另一個資源檔案中。
若要設定應用程式樣式
在 [方案總管] 中,將新資源字典加入到 VideoBrowser 專案。 如需詳細資訊,請參閱逐步解說:管理您 WPF 專案中的資源。
將自動產生的 XAML 替換成下列 XAML。
<ResourceDictionary xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> <!-- Listbox Style --> <Style TargetType="{x:Type ListBox}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBox}" > <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="6" Background="{DynamicResource ListBoxGradient}" > <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto"> <StackPanel IsItemsHost="True" Orientation="Horizontal" HorizontalAlignment="Left" /> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- Gradients --> <LinearGradientBrush x:Key="ListBoxGradient" StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStop Color="#90000000" Offset="0" /> <GradientStop Color="#40000000" Offset="0.005" /> <GradientStop Color="#10000000" Offset="0.04" /> <GradientStop Color="#20000000" Offset="0.945" /> <GradientStop Color="#60FFFFFF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="VerticalScrollGradient" StartPoint="0,0" EndPoint="1,0"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FDB6CADF" Offset="0" /> <GradientStop Color="#FCC3C5FF" Offset="0.1" /> <GradientStop Color="#FCC4D0EF" Offset="0.3" /> <GradientStop Color="#FDB7C2DF" Offset="0.6" /> <GradientStop Color="#FE95B3CF" Offset="0.8" /> <GradientStop Color="#FE96AACF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="WindowGradient" StartPoint="0,0.3" EndPoint="1,0"> <LinearGradientBrush.GradientStops> <GradientStop Color="#B2B6CAFF" Offset="0" /> <GradientStop Color="#BFC3D5FF" Offset="0.1" /> <GradientStop Color="#E0E4F0FF" Offset="0.3" /> <GradientStop Color="#E6EAF5FF" Offset="0.5" /> <GradientStop Color="#CFD7E2FF" Offset="0.6" /> <GradientStop Color="#BFC5D3FF" Offset="0.8" /> <GradientStop Color="#C4CBD8FF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <!-- PHOTOLIST STORYBOARDS --> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="MaxHeight" Value="100" /> <Setter Property="MinHeight" Value="100" /> <Setter Property="Opacity" Value=".75" /> <Style.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="MaxHeight" To="110" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" To="1.0" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="MaxHeight" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Style.Triggers> </Style> <!-- SCROLLBAR TEMPLATES --> <Style x:Key="Scrollbar_LineButton" TargetType="{x:Type RepeatButton}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Border BorderBrush="Transparent" BorderThickness="1" CornerRadius="6" Background="{DynamicResource ButtonGradient}"> <ContentPresenter x:Name="ContentSite" /> </Border> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="12" /> <Setter Property="MinWidth" Value="12" /> <Setter Property="Foreground" Value="Gray" /> <Setter Property="FontSize" Value="6pt" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="FontFamily" Value="Lucida Sans" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> <Style x:Key="ScrollBar_TrackRepeater" TargetType="{x:Type RepeatButton}"> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Command" Value="ScrollBar.PageUpCommand" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="Transparent" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="ScrollBar_UpTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageUpCommand" /> </Style> <Style x:Key="ScrollBar_DownTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageDownCommand" /> </Style> <Style x:Key="ScrollBar_LeftTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageLeftCommand" /> </Style> <Style x:Key="ScrollBar_RightTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageRightCommand" /> </Style> <Style x:Key="ScrollBar_VerticalThumb" TargetType="{x:Type Thumb}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Thumb}"> <Border CornerRadius="6" BorderBrush="Transparent" BorderThickness="1" Background="{DynamicResource VerticalScrollGradient}" /> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="10" /> <Setter Property="MinWidth" Value="10" /> </Style> <Style x:Key="ScrollBar_HorizontalThumb" TargetType="{x:Type Thumb}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Thumb}"> <Border CornerRadius="6" BorderBrush="Transparent" BorderThickness="1" Background="{DynamicResource ButtonGradient}" /> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="10" /> <Setter Property="MinWidth" Value="10" /> </Style> <Style TargetType="{x:Type ScrollBar}"> <Setter Property="Background" Value="Transparent" /> <Setter Property="MinWidth" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="10"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="10" /> <RowDefinition Height="*"/> <RowDefinition Height="10" /> </Grid.RowDefinitions> <Border Grid.Row="1" BorderThickness="0" Background="Transparent" CornerRadius="4"/> <RepeatButton Grid.Row="0" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineUpCommand" Content=" ^" /> <Track Grid.Row="1" Name="PART_Track" IsDirectionReversed="True"> <Track.IncreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_DownTrack}"/> </Track.IncreaseRepeatButton> <Track.DecreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_UpTrack}"/> </Track.DecreaseRepeatButton> <Track.Thumb> <Thumb Style="{DynamicResource ScrollBar_VerticalThumb}"/> </Track.Thumb> </Track> <RepeatButton Grid.Row="2" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineDownCommand" Content=" v" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="Orientation" Value="Horizontal" > <Setter Property="Background" Value="Transparent" /> <Setter Property="MinHeight" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="12"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="12" /> <ColumnDefinition Width="*"/> <ColumnDefinition Width="12" /> </Grid.ColumnDefinitions> <Border Grid.Column="1" BorderThickness="0" Background="Transparent" CornerRadius="4"/> <RepeatButton Grid.Column="0" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineLeftCommand" Content=" <" /> <Track Grid.Column="1" Name="PART_Track"> <Track.IncreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_RightTrack}"/> </Track.IncreaseRepeatButton> <Track.DecreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_LeftTrack}"/> </Track.DecreaseRepeatButton> <Track.Thumb> <Thumb Style="{DynamicResource ScrollBar_HorizontalThumb}"/> </Track.Thumb> </Track> <RepeatButton Grid.Column="2" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineRightCommand" Content=" >" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Viewbox x:Name="view" ClipToBounds="False" Stretch="Fill" Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}"> <Canvas Width="100" Height ="50" Margin="2"> <Rectangle x:Name="up" Canvas.Top="0" RadiusX="25" RadiusY="25" Width="100" Height="50" Stroke="Black" StrokeThickness="1"> <Rectangle.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#F53" /> <GradientStop Offset="1" Color="#FAA" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="down" Visibility="Collapsed" Canvas.Top="0" RadiusX="25" RadiusY="25" Width="100" Height="50" Stroke="Black" StrokeThickness="1"> <Rectangle.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#D88" /> <GradientStop Offset="1" Color="#D31" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="highlight" Canvas.Left="10" Canvas.Top="5" RadiusX="10" RadiusY="10" Width="80" Height="20" StrokeThickness="0"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#FFFF" /> <GradientStop Offset="1" Color="#0FFF" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Grid Width="100" Height="50"> <ContentPresenter VerticalAlignment="{TemplateBinding Property=VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding Property=HorizontalContentAlignment}" Content="{TemplateBinding Property=ContentControl.Content}"/> </Grid> </Canvas> </Viewbox> <ControlTemplate.Triggers> <Trigger Property="Button.IsMouseOver" Value="true"> <Setter Property = "Foreground" Value="White"/> </Trigger> <Trigger Property="Button.IsPressed" Value="true"> <Setter TargetName="up" Property="Visibility" Value="Collapsed"/> <Setter TargetName="down" Property="Visibility" Value="Visible"/> <Setter TargetName="highlight" Property="Visibility" Value="Collapsed"/> <Setter Property = "Foreground" Value="Black"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
<ResourceDictionary xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"> <!-- Listbox Style --> <Style TargetType="{x:Type ListBox}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBox}" > <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="6" Background="{DynamicResource ListBoxGradient}" > <ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Auto"> <StackPanel IsItemsHost="True" Orientation="Horizontal" HorizontalAlignment="Left" /> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- Gradients --> <LinearGradientBrush x:Key="ListBoxGradient" StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStop Color="#90000000" Offset="0" /> <GradientStop Color="#40000000" Offset="0.005" /> <GradientStop Color="#10000000" Offset="0.04" /> <GradientStop Color="#20000000" Offset="0.945" /> <GradientStop Color="#60FFFFFF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="VerticalScrollGradient" StartPoint="0,0" EndPoint="1,0"> <LinearGradientBrush.GradientStops> <GradientStop Color="#FDB6CADF" Offset="0" /> <GradientStop Color="#FCC3C5FF" Offset="0.1" /> <GradientStop Color="#FCC4D0EF" Offset="0.3" /> <GradientStop Color="#FDB7C2DF" Offset="0.6" /> <GradientStop Color="#FE95B3CF" Offset="0.8" /> <GradientStop Color="#FE96AACF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <LinearGradientBrush x:Key="WindowGradient" StartPoint="0,0.3" EndPoint="1,0"> <LinearGradientBrush.GradientStops> <GradientStop Color="#B2B6CAFF" Offset="0" /> <GradientStop Color="#BFC3D5FF" Offset="0.1" /> <GradientStop Color="#E0E4F0FF" Offset="0.3" /> <GradientStop Color="#E6EAF5FF" Offset="0.5" /> <GradientStop Color="#CFD7E2FF" Offset="0.6" /> <GradientStop Color="#BFC5D3FF" Offset="0.8" /> <GradientStop Color="#C4CBD8FF" Offset="1" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> <!-- PHOTOLIST STORYBOARDS --> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="MaxHeight" Value="100" /> <Setter Property="MinHeight" Value="100" /> <Setter Property="Opacity" Value=".75" /> <Style.Triggers> <EventTrigger RoutedEvent="Mouse.MouseEnter"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="MaxHeight" To="110" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" To="1.0" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> <EventTrigger RoutedEvent="Mouse.MouseLeave"> <EventTrigger.Actions> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="MaxHeight" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" /> </Storyboard> </BeginStoryboard> </EventTrigger.Actions> </EventTrigger> </Style.Triggers> </Style> <!-- SCROLLBAR TEMPLATES --> <Style x:Key="Scrollbar_LineButton" TargetType="{x:Type RepeatButton}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Border BorderBrush="Transparent" BorderThickness="1" CornerRadius="6" Background="{DynamicResource ButtonGradient}"> <ContentPresenter x:Name="ContentSite" /> </Border> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="12" /> <Setter Property="MinWidth" Value="12" /> <Setter Property="Foreground" Value="Gray" /> <Setter Property="FontSize" Value="6pt" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="FontFamily" Value="Lucida Sans" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Center" /> </Style> <Style x:Key="ScrollBar_TrackRepeater" TargetType="{x:Type RepeatButton}"> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Command" Value="ScrollBar.PageUpCommand" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type RepeatButton}"> <Rectangle Fill="Transparent" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="ScrollBar_UpTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageUpCommand" /> </Style> <Style x:Key="ScrollBar_DownTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageDownCommand" /> </Style> <Style x:Key="ScrollBar_LeftTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageLeftCommand" /> </Style> <Style x:Key="ScrollBar_RightTrack" BasedOn="{StaticResource ScrollBar_TrackRepeater}" TargetType="{x:Type RepeatButton}"> <Setter Property="Command" Value="ScrollBar.PageRightCommand" /> </Style> <Style x:Key="ScrollBar_VerticalThumb" TargetType="{x:Type Thumb}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Thumb}"> <Border CornerRadius="6" BorderBrush="Transparent" BorderThickness="1" Background="{DynamicResource VerticalScrollGradient}" /> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="10" /> <Setter Property="MinWidth" Value="10" /> </Style> <Style x:Key="ScrollBar_HorizontalThumb" TargetType="{x:Type Thumb}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Thumb}"> <Border CornerRadius="6" BorderBrush="Transparent" BorderThickness="1" Background="{DynamicResource ButtonGradient}" /> </ControlTemplate> </Setter.Value> </Setter> <Setter Property="MinHeight" Value="10" /> <Setter Property="MinWidth" Value="10" /> </Style> <Style TargetType="{x:Type ScrollBar}"> <Setter Property="Background" Value="Transparent" /> <Setter Property="MinWidth" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="10"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="10" /> <RowDefinition Height="*"/> <RowDefinition Height="10" /> </Grid.RowDefinitions> <Border Grid.Row="1" BorderThickness="0" Background="Transparent" CornerRadius="4"/> <RepeatButton Grid.Row="0" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineUpCommand" Content=" ^" /> <Track Grid.Row="1" Name="PART_Track" IsDirectionReversed="True"> <Track.IncreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_DownTrack}"/> </Track.IncreaseRepeatButton> <Track.DecreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_UpTrack}"/> </Track.DecreaseRepeatButton> <Track.Thumb> <Thumb Style="{DynamicResource ScrollBar_VerticalThumb}"/> </Track.Thumb> </Track> <RepeatButton Grid.Row="2" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineDownCommand" Content=" v" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="Orientation" Value="Horizontal" > <Setter Property="Background" Value="Transparent" /> <Setter Property="MinHeight" Value="10" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollBar}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="12"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="12" /> <ColumnDefinition Width="*"/> <ColumnDefinition Width="12" /> </Grid.ColumnDefinitions> <Border Grid.Column="1" BorderThickness="0" Background="Transparent" CornerRadius="4"/> <RepeatButton Grid.Column="0" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineLeftCommand" Content=" <" /> <Track Grid.Column="1" Name="PART_Track"> <Track.IncreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_RightTrack}"/> </Track.IncreaseRepeatButton> <Track.DecreaseRepeatButton> <RepeatButton Style="{DynamicResource ScrollBar_LeftTrack}"/> </Track.DecreaseRepeatButton> <Track.Thumb> <Thumb Style="{DynamicResource ScrollBar_HorizontalThumb}"/> </Track.Thumb> </Track> <RepeatButton Grid.Column="2" Style="{DynamicResource Scrollbar_LineButton}" Command="ScrollBar.LineRightCommand" Content=" >" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Trigger> </Style.Triggers> </Style> <Style TargetType="{x:Type Button}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <Viewbox x:Name="view" ClipToBounds="False" Stretch="Fill" Width="{TemplateBinding Property=Width}" Height="{TemplateBinding Property=Height}"> <Canvas Width="100" Height ="50" Margin="2"> <Rectangle x:Name="up" Canvas.Top="0" RadiusX="25" RadiusY="25" Width="100" Height="50" Stroke="Black" StrokeThickness="1"> <Rectangle.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#F53" /> <GradientStop Offset="1" Color="#FAA" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="down" Visibility="Collapsed" Canvas.Top="0" RadiusX="25" RadiusY="25" Width="100" Height="50" Stroke="Black" StrokeThickness="1"> <Rectangle.Fill> <LinearGradientBrush> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#D88" /> <GradientStop Offset="1" Color="#D31" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="highlight" Canvas.Left="10" Canvas.Top="5" RadiusX="10" RadiusY="10" Width="80" Height="20" StrokeThickness="0"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <LinearGradientBrush.GradientStops> <GradientStop Offset="0" Color="#FFFF" /> <GradientStop Offset="1" Color="#0FFF" /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Grid Width="100" Height="50"> <ContentPresenter VerticalAlignment="{TemplateBinding Property=VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding Property=HorizontalContentAlignment}" Content="{TemplateBinding Property=ContentControl.Content}"/> </Grid> </Canvas> </Viewbox> <ControlTemplate.Triggers> <Trigger Property="Button.IsMouseOver" Value="true"> <Setter Property = "Foreground" Value="White"/> </Trigger> <Trigger Property="Button.IsPressed" Value="true"> <Setter TargetName="up" Property="Visibility" Value="Collapsed"/> <Setter TargetName="down" Property="Visibility" Value="Visible"/> <Setter TargetName="highlight" Property="Visibility" Value="Collapsed"/> <Setter Property = "Foreground" Value="Black"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
開啟 MainWindow.xaml,然後將下列在 MainWindow 項目開頭標記之後的 XAML 標記為註解。
<vb:FileToURIConverter x:Key="myConverter" /> <DataTemplate x:Key="imageTemplate"> <Border VerticalAlignment="Center" HorizontalAlignment="Center" Padding="4" Margin="2" Background="White"> <Image Source="{Binding Converter={StaticResource myConverter}}" /> </Border> </DataTemplate>
取消註解下列 XAML。
<!--<ResourceDictionary > <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources.xaml"/> </ResourceDictionary.MergedDictionaries> <vb:FileToURIConverter x:Key="myConverter" /> <DataTemplate x:Key="imageTemplate"> <Border VerticalAlignment="Center" HorizontalAlignment="Center" Padding="4" Margin="2" Background="White"> <Image Source="{Binding Converter={StaticResource myConverter}}" /> </Border> </DataTemplate> </ResourceDictionary>-->
按一下 [設計] 檢視,將 XAML 載入到設計介面。
新樣式就會套用到設計介面上的控制項。
按 F5 建置並執行應用程式。