Пошаговое руководство. Построение видеообозревателя с помощью конструктора WPF
Обновлен: Ноябрь 2007
В этом руководстве демонстрируется использование конструктора Windows Presentation Foundation (WPF) для Visual Studio (конструктор) для создания приложения WPF для просмотра видеофайлов.
В данном руководстве нужно выполнить следующие задачи:
Создание проекта,
Создание макета.
Добавление в макет элементов управления,
Задание свойств, относящихся к макету,
Создание типа источника данных,
Создание элемента управления WPF,
Использование элемента управления в приложении,
Реализация логики приложения,
Включение привязки данных,
Настройка стиля приложения.
На следующем рисунке показано, как будет выглядеть приложение.
По окончании работы будет создано приложение, позволяющее просматривать файлы проигрывателя Windows Media (WMV) в папке. У каждого WMV-файла должен быть соответствующий файл с расширением JPG с тем же именем. Например, у файла bear.wmv должен быть файл bear.jpg в той же папке.
Примечание. |
---|
Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих параметров или версии среды. Для изменения параметров в меню Сервис выберите команду Импорт и экспорт параметров. Дополнительные сведения см. в разделе Параметры Visual Studio. |
Примечание. |
---|
Следующая ниже информация приводится с разрешения компании Application Developers Training Company, владельца и создателя данного исходного кода/примера. Оригинальное использование показывается в обучающей системе Кена Гетца "Разработка приложений для Visual Studio 2008", авторское право 2007, Application Developers Training Company. Дополнительные сведения см. по адресу http://www.appdev.com. |
Обязательные компоненты
Для выполнения данного пошагового руководства необходимы следующие компоненты.
- Visual Studio 2008.
Создание проекта
Первым этапом является создание проекта ведущего приложения. MoviePlayerControl является элементом UserControl, который содержит MediaElement и другие элементы для управления воспроизведением видео.
Создание проекта
Создайте проект приложения WPF с именем VideoBrowser. Дополнительные сведения см. в разделе Практическое руководство. Создание нового проекта приложения WPF.
Файл Window1.xaml откроется в средстве WPF (конструктор).
Добавьте в решение новый проект библиотеки пользовательских элементов управления WPF. Назовите проект MoviePlayerControlLibrary. Дополнительные сведения см. в разделе Практическое руководство. Создание проекта библиотеки элементов UserControl в WPF.
В проекте MoviePlayerControlLibrary добавьте новый пользовательский элемент управления WPF с именем MoviePlayerControl . Дополнительные сведения см. в разделе Практическое руководство. Добавление новых элементов в проекте WPF.
Удалите UserControl1 из проекта.
Создание макета
Макет определяет расположение элементов управления в главном окне приложения. Следующие действия показывают создание элементов макета, которые будут содержать элементы управления приложения.
Создание макета
Откройте файл MediaPlayerControl.xaml в конструкторе WPF (конструктор).
Выберите корневой элемент управления Grid в пользовательском элементе управления. Дополнительные сведения см. в разделе Практическое руководство. Выбор и перемещение элементов в область конструктора.
В окне "Свойства" укажите имя корневого элемента управления GridmoviePlayerGrid. Свойство "Имя" указывается в верхней части окна "Свойства".
Добавьте две дополнительные строки в moviePlayerGrid. Дополнительные сведения см. в разделе Практическое руководство. Добавление строк и столбцов в таблицу.
В окне "Структура документа" выберите первую строку в moviePlayerGrid и задайте для свойства MinHeight значение 50.
Выберите вторую строку в moviePlayerGrid и установите для Height значение 20.
Выберите третью строку в moviePlayerGrid и установите для Height значение 55.
Перетащите элемент управления Grid из панели элементов в третью строку moviePlayerGrid.
В WPF (конструктор) создается новый элемент управления Grid с именем grid1.
В окне "Свойства" измените имя grid1 на mediaControlsGrid.
Установите для свойства Margin элемента mediaControlsGrid значение 0.
В окне "Свойства" откройте редактор коллекции ColumnDefinitions и добавьте пять определений столбцов.
Из панели элементов перетащите элемент управления StackPanel в последний столбец mediaControlsGrid.
В WPF (конструктор) создается новый элемент управления StackPanel с именем stackPanel1.
Откройте окно "Структура документа" для проверки макета. Дополнительные сведения см. в разделе Навигация по иерархии элементов документа 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. Дополнительные сведения см. в разделе Практическое руководство. Создание простого обработчика событий.
Добавление обработчиков событий
В представлении XAML поместите курсор в тег <MediaElement> и введите MediaOpened =.
Технология Intellisense представляет параметр <New Event Handler>.
Выберите элемент <New Event Handler>.
В WPF (конструктор) создается обработчик событий moviePlayer_MediaOpened в файле с текстом программы.
Повторите действия 1 и 2 для события MediaEnded.
В представлении "Конструктор" дважды щелкните объект positionSlider.
В WPF (конструктор) создается обработчик событий positionSlider_ValueChanged в файле с текстом программы.
В представлении "Конструктор" дважды щелкните объект backButton.
В WPF (конструктор) создается обработчик событий backButton_Click в файле с текстом программы.
Дважды щелкните оставшиеся элементы управления-кнопки для создания обработчиков событий Click для каждого из них.
Дважды щелкните объект positionSlider для создания обработчика событий ValueChanged.
Реализация действий для MoviePlayerControl
Действия для элемента MoviePlayerControl реализуются в файле с текстом программы, который называется MoviePlayerControl.XAML.cs или MoviePlayerControl.XAML.vb.
Реализация действия для 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.
Откройте файл Window1.xaml и в представлении XAML замените автоматически создаваемый код на следующий код.
<Window x:Class="VideoBrowser.Window1" 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>
<Window x:Class="VideoBrowser.Window1" 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>
Откройте файл кода с именем Window1.xaml.cs или Window1.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 Window1 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 Window1 : Window { public Window1() { 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>
Откройте файл Window1.xaml и установите комментарий для следующего XAML-кода после открывающего тега элемента Window1.
<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>
<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>-->
<!--<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 для построения и выполнения приложения.