Поделиться через


Пошаговое руководство. Построение видеообозревателя с помощью конструктора WPF

Обновлен: Ноябрь 2007

В этом руководстве демонстрируется использование конструктора Windows Presentation Foundation (WPF) для Visual Studio (конструктор) для создания приложения WPF для просмотра видеофайлов.

В данном руководстве нужно выполнить следующие задачи:

  • Создание проекта,

  • Создание макета.

  • Добавление в макет элементов управления,

  • Задание свойств, относящихся к макету,

  • Создание типа источника данных,

  • Создание элемента управления WPF,

  • Использование элемента управления в приложении,

  • Реализация логики приложения,

  • Включение привязки данных,

  • Настройка стиля приложения.

На следующем рисунке показано, как будет выглядеть приложение.

Видео-обозреватель, созданный при помощи конструктора WPF

По окончании работы будет создано приложение, позволяющее просматривать файлы проигрывателя Windows Media (WMV) в папке. У каждого WMV-файла должен быть соответствующий файл с расширением JPG с тем же именем. Например, у файла bear.wmv должен быть файл bear.jpg в той же папке.

Bb546936.alert_note(ru-ru,VS.90).gifПримечание.

Отображаемые диалоговые окна и команды меню могут отличаться от описанных в справке в зависимости от текущих параметров или версии среды. Для изменения параметров в меню Сервис выберите команду Импорт и экспорт параметров. Дополнительные сведения см. в разделе Параметры Visual Studio.

Bb546936.alert_note(ru-ru,VS.90).gifПримечание.

Следующая ниже информация приводится с разрешения компании Application Developers Training Company, владельца и создателя данного исходного кода/примера. Оригинальное использование показывается в обучающей системе Кена Гетца "Разработка приложений для Visual Studio 2008", авторское право 2007, Application Developers Training Company. Дополнительные сведения см. по адресу http://www.appdev.com.

Обязательные компоненты

Для выполнения данного пошагового руководства необходимы следующие компоненты.

  • Visual Studio 2008.

Создание проекта

Первым этапом является создание проекта ведущего приложения. MoviePlayerControl является элементом UserControl, который содержит MediaElement и другие элементы для управления воспроизведением видео.

Создание проекта

  1. Создайте проект приложения WPF с именем VideoBrowser. Дополнительные сведения см. в разделе Практическое руководство. Создание нового проекта приложения WPF.

    Файл Window1.xaml откроется в средстве WPF (конструктор).

  2. Добавьте в решение новый проект библиотеки пользовательских элементов управления WPF. Назовите проект MoviePlayerControlLibrary. Дополнительные сведения см. в разделе Практическое руководство. Создание проекта библиотеки элементов UserControl в WPF.

  3. В проекте MoviePlayerControlLibrary добавьте новый пользовательский элемент управления WPF с именем MoviePlayerControl . Дополнительные сведения см. в разделе Практическое руководство. Добавление новых элементов в проекте WPF.

  4. Удалите UserControl1 из проекта.

Создание макета

Макет определяет расположение элементов управления в главном окне приложения. Следующие действия показывают создание элементов макета, которые будут содержать элементы управления приложения.

Создание макета

  1. Откройте файл MediaPlayerControl.xaml в конструкторе WPF (конструктор).

  2. Выберите корневой элемент управления Grid в пользовательском элементе управления. Дополнительные сведения см. в разделе Практическое руководство. Выбор и перемещение элементов в область конструктора.

  3. В окне "Свойства" укажите имя корневого элемента управления GridmoviePlayerGrid. Свойство "Имя" указывается в верхней части окна "Свойства".

  4. Добавьте две дополнительные строки в moviePlayerGrid. Дополнительные сведения см. в разделе Практическое руководство. Добавление строк и столбцов в таблицу.

  5. В окне "Структура документа" выберите первую строку в moviePlayerGrid и задайте для свойства MinHeight значение 50.

  6. Выберите вторую строку в moviePlayerGrid и установите для Height значение 20.

  7. Выберите третью строку в moviePlayerGrid и установите для Height значение 55.

  8. Перетащите элемент управления Grid из панели элементов в третью строку moviePlayerGrid.

    В WPF (конструктор) создается новый элемент управления Grid с именем grid1.

  9. В окне "Свойства" измените имя grid1 на mediaControlsGrid.

  10. Установите для свойства Margin элемента mediaControlsGrid значение 0.

  11. В окне "Свойства" откройте редактор коллекции ColumnDefinitions и добавьте пять определений столбцов.

  12. Из панели элементов перетащите элемент управления StackPanel в последний столбец mediaControlsGrid.

    В WPF (конструктор) создается новый элемент управления StackPanel с именем stackPanel1.

  13. Откройте окно "Структура документа" для проверки макета. Дополнительные сведения см. в разделе Навигация по иерархии элементов документа WPF.

    Убедитесь, что иерархия объектов выглядит следующим образом:

    Grid (moviePlayerGrid),

        RowDefinitions,

        Grid (mediaControlsGrid),

            ColumnDefinitions,

            StackPanel (stackPanel1).

    Если иерархия объектов не соответствует этому образцу, следует переместить объекты или изменить XAML-код, чтобы получить такую иерархию.

Добавление элементов управления в макет

Если макет определен, его можно заполнить элементами управления. Щелкните нужный элемент управления в панели элементов и переместите его в область конструктора.

Добавление в макет элементов управления

  1. Перетащите элемент управления MediaElement из панели элементов в первую строку moviePlayerGrid.

  2. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    moviePlayer

    Margin

    0

    Width

    Auto

    Height

    Auto

    HorizontalAlignment

    Stretch

    VerticalAlignment

    Stretch

    LoadedBehavior

    Manual

  3. Из панели элементов перетащите элемент управления Button в первый столбец mediaControlsGrid.

  4. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    backButton

    Content

    Back

    Margin

    0

  5. Из панели элементов перетащите элемент управления Button во второй столбец mediaControlsGrid.

  6. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    playButton

    Content

    Play

    Margin

    0

  7. Из панели элементов перетащите элемент управления Button в третий столбец mediaControlsGrid.

  8. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    stopButton

    Content

    Stop

    Margin

    0

  9. Из панели элементов перетащите элемент управления Button в четвертый столбец mediaControlsGrid.

  10. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    forwardButton

    Content

    Fwd

    Margin

    0

  11. Из панели элементов перетащите элемент управления TextBlock в пятый столбец mediaControlsGrid.

  12. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Text

    Volume

    Width

    Auto

    Height

    Auto

    HorizontalAlignment

    Center

    VerticalAlignment

    Stretch

  13. Из панели элементов перетащите элемент управления Slider в пятый столбец mediaControlsGrid.

  14. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    volumeSlider

    Width

    Auto

    Height

    Auto

    Minimum

    0

    Maximum

    1

    Margin

    5

  15. Перетащите элемент управления Slider из панели элементов во вторую строку moviePlayerGrid.

  16. В окне "Свойства" установите следующие свойства, как показано ниже.

    Свойство

    Значение

    Name

    positionSlider

    Width

    Auto

    Height

    Auto

    Minimum

    0

    Maximum

    1

    Margin

    2

    HorizontalAlignment

    Stretch

    VerticalAlignment

    Stretch

Добавление обработчиков событий

Приложение отвечает на ввод пользователя обработкой событий. Следующая процедура описывает добавление обработчиков событий для событий, которые вызываются элементами управления в MoviePlayerControl. Дополнительные сведения см. в разделе Практическое руководство. Создание простого обработчика событий.

Добавление обработчиков событий

  1. В представлении XAML поместите курсор в тег <MediaElement> и введите MediaOpened =.

    Технология Intellisense представляет параметр <New Event Handler>.

  2. Выберите элемент <New Event Handler>.

    В WPF (конструктор) создается обработчик событий moviePlayer_MediaOpened в файле с текстом программы. 

  3. Повторите действия 1 и 2 для события MediaEnded.

  4. В представлении "Конструктор" дважды щелкните объект positionSlider.

    В WPF (конструктор) создается обработчик событий positionSlider_ValueChanged в файле с текстом программы.

  5. В представлении "Конструктор" дважды щелкните объект backButton.

    В WPF (конструктор) создается обработчик событий backButton_Click в файле с текстом программы.

  6. Дважды щелкните оставшиеся элементы управления-кнопки для создания обработчиков событий Click для каждого из них.

  7. Дважды щелкните объект positionSlider для создания обработчика событий ValueChanged.

Реализация действий для MoviePlayerControl

Действия для элемента MoviePlayerControl реализуются в файле с текстом программы, который называется MoviePlayerControl.XAML.cs или MoviePlayerControl.XAML.vb.

Реализация действия для MoviePlayerControl

  1. В обозревателе решений дважды щелкните MoviePlayerControl.xaml.cs или MoviePlayerControl.xaml.vb, чтобы открыть файл с текстом программы в редакторе кода.

  2. Вставьте следующий код в определение класса 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();
    
  3. Вставьте следующий код в определение класса 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
    
    
  4. Замените автоматически созданные обработчики событий следующим кодом.

    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;
    }
    
  5. Замените автоматически создаваемый конструктор на следующий код.

    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);
    }
    
  6. Вставьте следующие методы для определения общего интерфейса элемента управления.

    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();
    }
    
  7. Нажмите клавишу F6, чтобы создать элемент управления.

Создание типа источника данных

Подключение элементов управления к данным осуществляется с помощью привязки данных. Для этого приложения элемент управления ListBox видеообозревателя привязан к настраиваемому классу с именем ThumbnailList.

Создание типа источника данных

  1. Добавьте новый класс с именем ThumbnailList в проект VideoBrowser.

  2. Откройте файл 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);
                    }
                }
            }
        }
    }
    
  3. Добавьте новый класс с именем FileToURIConverter в проект VideoBrowser.

  4. Откройте файл 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();
            }
        }
    }
    
  5. Сохраните все файлы.

Использование элемента управления в приложении

После создания элемента управления его можно использовать в приложении.

Использование элемента управления WPF

  1. В проекте VideoBrowser обозревателя решений добавьте ссылку на проект MoviePlayerControlLibrary. Дополнительные сведения см. в разделе Ссылки проекта.

  2. Добавьте ссылку на сборку System.Windows.Forms. Это необходимо для элемента FolderBrowserDialog.

  3. Откройте файл 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>
    
  4. Откройте файл кода с именем 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 отображается со стилем по умолчанию. Путем создания и применения стилей можно изменить внешний вид и поведение приложения. Стили часто хранятся в отдельном файле ресурсов.

Настройка стиля приложения

  1. В обозревателе решений добавьте новый словарь ресурсов в проект VideoBrowser. Дополнительные сведения см. в разделе Пошаговое руководство. Управление ресурсами в проекте WPF.

  2. Замените автоматически созданный 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=" &lt;" />
                                    <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=" &gt;" />
    
                                </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=" &lt;" />
                                    <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=" &gt;" />
    
                                </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>
    
  3. Откройте файл 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>
    
  4. Удалите комментарий следующего 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>-->
    
  5. Выберите файл в представлении "Конструктор" для загрузки XAML-кода в область конструктора.

    Новые стили будут применены к элементам управления в области конструктора.

  6. Нажмите клавишу F5 для построения и выполнения приложения.

См. также

Другие ресурсы

Миграция и взаимодействие систем

Работа с элементами управления в конструкторе WPF