Freigeben über


Exemplarische Vorgehensweise: Erstellen eines Videobrowsers mit dem WPF-Designer

In dieser exemplarischen Vorgehensweise wird erläutert, wie der WPF Designer für Visual Studio verwendet werden kann, um eine WPF-Anwendung zum Durchsuchen von Videodateien zu erstellen.

Im Verlauf dieser exemplarischen Vorgehensweise führen Sie folgende Aufgaben aus:

  • Erstellen des Projekts

  • Erstellen des Layouts.

  • Hinzufügen von Steuerelementen zum Layout

  • Festlegen von layoutbezogenen Eigenschaften

  • Erstellen eines Datenquellentyps

  • Erstellen des WPF-Steuerelements

  • Verwenden des Steuerelements in der Anwendung

  • Implementieren der Anwendungslogik

  • Aktivieren der Datenbindung

  • Festlegen von Stilen für die Anwendung

Die folgende Abbildung zeigt, wie die Anwendung angezeigt wird.

Mit dem WPF-Designer erstellter Videobrowser

Am Ende des Prozesses verfügen Sie über eine Anwendung, mit der Sie einen Ordner nach WMV (Windows Media Player)-Dateien durchsuchen können. Für jede WMV-Datei muss eine entsprechende JPG-Datei mit dem gleichen Namen vorhanden sein. Zum Beispiel muss sich für bear.wmv die Datei bear.jpg im gleichen Ordner befinden.

Tipp

Je nach den aktiven Einstellungen oder der Version unterscheiden sich die Dialogfelder und Menübefehle auf Ihrem Bildschirm möglicherweise von den in der Hilfe beschriebenen. Klicken Sie im Menü Extras auf Einstellungen importieren und exportieren, um die Einstellungen zu ändern. Weitere Informationen finden Sie unter Arbeiten mit Einstellungen.

Tipp

Folgende Angaben erfolgen mit Genehmigung von Application Developers Training Company, dem Eigentümer und Autor dieses Quellcodes/Beispiels. Die ursprüngliche Verwendung ist in der Courseware "Developing Applications for Visual Studio 2008" von Ken Getz, Copyright 2007 Application Developers Training Company, dargestellt. Weitere Informationen finden Sie unter http://www.appdev.com.

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:

  • Visual Studio 2010.

Erstellen des Projekts

Der erste Schritt besteht darin, das Projekt für die Hostanwendung zu erstellen. Das MoviePlayerControl ist ein UserControl, das ein MediaElement und andere Steuerelemente zum Bearbeiten der Videowiedergabe enthält.

So erstellen Sie das Projekt

  1. Erstellen Sie ein WPF-Anwendungsprojekt mit dem Namen VideoBrowser. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines neuen WPF-Anwendungsprojekts.

    Die Datei MainWindow.xaml wird im WPF-Designer geöffnet.

  2. Fügen Sie der Projektmappe ein neues WPF-Benutzersteuerelementbibliothek-Projekt hinzu. Nennen Sie das Projekt MoviePlayerControlLibrary. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines WPF-UserControl-Bibliotheksprojekts.

  3. Fügen Sie dem MoviePlayerControlLibrary-Projekt ein neues WPF-Benutzersteuerelement mit dem Namen MoviePlayerControl hinzu. Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen von neuen Elementen zu einem WPF-Projekt.

  4. Löschen Sie UserControl1 aus dem Projekt.

Erstellen des Layouts

Durch das Layout wird definiert, wie die Steuerelemente im Hauptfenster der Anwendung angeordnet werden. In den folgenden Schritten wird dargestellt, wie die Layoutelemente erstellt werden, die die Steuerelemente der Anwendung enthalten.

So erstellen Sie das Layout

  1. Öffnen Sie die Datei MediaPlayerControl.xaml im WPF-Designer.

  2. Wählen Sie im Benutzersteuerelement das Grid-Stammsteuerelement aus. Weitere Informationen finden Sie unter Gewusst wie: Auswählen und Verschieben von Elementen auf der Entwurfsoberfläche.

  3. Legen Sie im Eigenschaftenfenster den Namen des Grid-Stammsteuerelements auf moviePlayerGrid fest. Die Name-Eigenschaft wird oben im Eigenschaftenfenster festgelegt.

  4. Fügen Sie zwei weitere Zeilen zu moviePlayerGrid hinzu. Weitere Informationen finden Sie unter Gewusst wie: Hinzufügen von Zeilen und Spalten zu einem Raster.

  5. Wählen Sie im Fenster Dokumentgliederung die erste Zeile in moviePlayerGrid aus, und legen Sie die MinHeight-Eigenschaft auf 50 fest.

  6. Wählen Sie die zweite Zeile im moviePlayerGrid aus, und legen Sie die Height auf 20 fest.

  7. Wählen Sie die dritte Zeile im moviePlayerGrid aus, und legen Sie die Height auf 55 fest.

  8. Ziehen Sie aus der Toolbox ein Grid-Steuerelement in die dritte Zeile im moviePlayerGrid.

    Der WPF-Designer erstellt ein neues Grid-Steuerelement mit dem Namen grid1.

  9. Legen Sie im Eigenschaftenfenster den Namen von grid1 auf mediaControlsGrid fest.

  10. Legen Sie die Margin-Eigenschaft von mediaControlsGrid auf 0 fest.

  11. Öffnen Sie im Eigenschaftenfenster den ColumnDefinitions-Auflistungs-Editor, und fügen Sie fünf Spaltendefinitionen hinzu.

  12. Ziehen Sie aus der Toolbox ein StackPanel-Steuerelement in die letzte Spalte im mediaControlsGrid.

    Der WPF-Designer erstellt ein neues StackPanel-Steuerelement mit dem Namen stackPanel1.

  13. Öffnen Sie das Fenster Dokumentgliederung, um das Layout zu überprüfen. Weitere Informationen finden Sie unter Navigieren in der Elementhierarchie eines WPF-Dokuments.

    Stellen Sie sicher, dass die Objekthierarchie folgendermaßen angezeigt wird:

    Grid (moviePlayerGrid)

        RowDefinitions

        Grid (mediaControlsGrid)

            ColumnDefinitions

            StackPanel (stackPanel1)

    Wenn die Objekthierarchie nicht diesem Muster folgt, ziehen Sie die Objekte, oder ändern Sie den XAML-Code, bis Sie diese Hierarchie erhalten.

Hinzufügen von Steuerelementen zum Layout

Das definierte Layout kann nun mit Steuerelementen gefüllt werden. Klicken Sie einfach auf das gewünschte Steuerelement in der Toolbox, und ziehen Sie es auf die Entwurfsoberfläche.

So fügen Sie Steuerelemente zum Layout hinzu

  1. Ziehen Sie aus der Toolbox ein MediaElement-Steuerelement in die erste Zeile im moviePlayerGrid.

  2. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    moviePlayer

    Margin

    0

    Breite

    Auto

    Höhe

    Auto

    HorizontalAlignment

    Stretch

    VerticalAlignment

    Stretch

    LoadedBehavior

    Manuell

  3. Ziehen Sie aus der Toolbox ein Button-Steuerelement in die erste Spalte im mediaControlsGrid.

  4. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    backButton

    Inhalt

    Back

    Margin

    0

  5. Ziehen Sie aus der Toolbox ein Button-Steuerelement in die zweite Spalte im mediaControlsGrid.

  6. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    playButton

    Inhalt

    Play

    Margin

    0

  7. Ziehen Sie aus der Toolbox ein Button-Steuerelement in die dritte Spalte im mediaControlsGrid.

  8. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    stopButton

    Inhalt

    Stop

    Margin

    0

  9. Ziehen Sie aus der Toolbox ein Button-Steuerelement in die vierte Spalte im mediaControlsGrid.

  10. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    forwardButton

    Inhalt

    Fwd

    Margin

    0

  11. Ziehen Sie aus der Toolbox ein TextBlock-Steuerelement in die fünfte Spalte im mediaControlsGrid.

  12. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Text

    Volume

    Breite

    Auto

    Höhe

    Auto

    HorizontalAlignment

    Center

    VerticalAlignment

    Stretch

  13. Ziehen Sie aus der Toolbox ein Slider-Steuerelement in die fünfte Spalte im mediaControlsGrid.

  14. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    volumeSlider

    Breite

    Auto

    Höhe

    Auto

    Minimum

    0

    Maximum

    1

    Margin

    5

  15. Ziehen Sie aus der Toolbox ein Slider-Steuerelement in die zweite Zeile im moviePlayerGrid.

  16. Legen Sie im Eigenschaftenfenster die folgenden Eigenschaften wie dargestellt fest.

    Eigenschaft

    Wert

    Name

    positionSlider

    Breite

    Auto

    Höhe

    Auto

    Minimum

    0

    Maximum

    1

    Margin

    2

    HorizontalAlignment

    Stretch

    VerticalAlignment

    Stretch

Hinzufügen von Ereignishandlern

Die Anwendung reagiert auf eine Benutzereingabe durch die Behandlung von Ereignissen. Im folgenden Verfahren wird veranschaulicht, wie Ereignishandler für Ereignisse hinzugefügt werden, die von Steuerelementen im MoviePlayerControl ausgelöst werden. Weitere Informationen finden Sie unter Gewusst wie: Erstellen eines einfachen Ereignishandlers.

So fügen Sie Ereignishandler hinzu

  1. Platzieren Sie in der XAML-Ansicht den Cursor im <MediaElement>-Tag, und geben Sie MediaOpened= ein.

    Intellisense zeigt die Option <Neuer Ereignishandler> an.

  2. Wählen Sie <Neuer Ereignishandler> aus.

    Der WPF-Designer erstellt den moviePlayer_MediaOpened-Ereignishandler in der Codedatei. 

  3. Wiederholen Sie die Schritte 1 und 2 für das MediaEnded-Ereignis.

  4. Doppelklicken Sie in der Entwurfsansicht auf positionSlider.

    Der WPF-Designer erstellt den positionSlider_ValueChanged-Ereignishandler in der Codedatei.

  5. Doppelklicken Sie in der Entwurfsansicht auf backButton.

    Der WPF-Designer erstellt den backButton_Click-Ereignishandler in der Codedatei.

  6. Doppelklicken Sie auf die verbleibenden Schaltflächen-Steuerelemente, um Click-Ereignishandler für jedes dieser Steuerelemente zu generieren.

  7. Doppelklicken Sie auf positionSlider, um den ValueChanged-Ereignishandler zu generieren.

Implementieren der Logik für das MoviePlayerControl

Implementieren Sie die Logik für das MoviePlayerControl in der Codedatei mit dem Namen MoviePlayerControl.xaml.cs oder MoviePlayerControl.xaml.vb.

So implementieren Sie die Logik für das MoviePlayerControl

  1. Doppelklicken Sie im Projektmappen-Explorer auf MoviePlayerControl.xaml.cs oder MoviePlayerControl.xaml.vb, um die Codedatei im Code-Editor zu öffnen.

  2. Fügen Sie den folgenden Code vor dem Konstruktor in die MoviePlayerControl-Klassendefinition ein.

    ' 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. Fügen Sie den folgenden Code nach den Ereignishandlerdefinitionen in die MoviePlayerControl-Klassendefinition ein.

    #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. Ersetzen Sie die automatisch generierten Ereignishandler durch den folgenden Code.

            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. Ersetzen Sie den automatisch generierten Konstruktor durch den folgenden Code.

    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. Fügen Sie die folgenden Methoden ein, um die öffentliche Schnittstelle des Steuerelements zu definieren.

    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. Drücken Sie F6, um das Steuerelement zu erstellen.

Erstellen eines Datenquellentyps

Die Steuerelemente werden mithilfe der Datenbindung mit Daten verbunden. Für diese Anwendung wird das ListBox-Steuerelement des Videobrowsers an eine benutzerdefinierte Klasse mit dem Namen ThumbnailList gebunden.

So erstellen Sie einen Datenquellentyp

  1. Fügen Sie dem Projekt VideoBrowser eine neue Klasse mit dem Namen ThumbnailList hinzu.

  2. Öffnen Sie die Datei ThumbnailList.cs oder ThumbnailList.vb im Code-Editor, und ersetzen Sie den automatisch generierten Code durch den folgenden Code.

    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. Fügen Sie dem Projekt VideoBrowser eine neue Klasse mit dem Namen FileToURIConverter hinzu.

  4. Öffnen Sie die Datei FileToURIConverter.cs oder FileToURIConverter.vb im Code-Editor, und ersetzen Sie den automatisch generierten Code durch den folgenden Code.

    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. Speichern Sie alle Dateien.

Verwenden des Steuerelements in der Anwendung

Wenn Sie das Steuerelement erstellt haben, können Sie es in der Anwendung verwenden.

So verwenden Sie das WPF-Steuerelement

  1. Fügen Sie im VideoBrowser-Projekt des Projektmappen-Explorers einen Verweis zum MoviePlayerControlLibrary-Projekt hinzu. Weitere Informationen finden Sie unter Projektverweise.

  2. Fügen Sie einen Verweis auf die System.Windows.Forms-Assembly hinzu. Dies ist für den FolderBrowserDialog erforderlich.

  3. Öffnen Sie die Datei MainWindow.xaml in der XAML-Ansicht, und ersetzen Sie den automatisch generierten Code durch den folgenden Code.

    <Window x:Class="VideoBrowser.MainWindow"
            Name="window1"
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:media = "clr-namespace:MoviePlayerControlLibrary;assembly=MoviePlayerControlLibrary"
            xmlns:vb="clr-namespace:VideoBrowser"
            Title="Video Browser" Height="540" Width="383">
        <Window.Resources>
    
            <vb:FileToURIConverter x:Key="myConverter" />
    
            <DataTemplate x:Key="imageTemplate">
                <Border VerticalAlignment="Center" 
                  HorizontalAlignment="Center" 
                  Padding="4" Margin="2" 
                  Background="White">
                    <Image Source="{Binding Converter={StaticResource myConverter}}" />
                </Border>
            </DataTemplate>
    
            <!--<ResourceDictionary >
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Resources.xaml"/>
                </ResourceDictionary.MergedDictionaries>
    
                <vb:FileToURIConverter x:Key="myConverter" />
    
                <DataTemplate x:Key="imageTemplate">
                    <Border VerticalAlignment="Center" 
                  HorizontalAlignment="Center" 
                  Padding="4" Margin="2" 
                  Background="White">
                        <Image Source="{Binding Converter={StaticResource myConverter}}" />
                    </Border>
                </DataTemplate>
            </ResourceDictionary>-->
    
    
    
        </Window.Resources>
    
    
    
        <Grid Name="grid1">
            <Grid.RowDefinitions>
                <RowDefinition Height="125" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid Margin="0" Name="grid2">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="115" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Button x:Name="selectFolderButton" Click="selectFolderButton_Click">Select folder...</Button>
                <ListBox Grid.Column="1" Margin="0,0,0,0" 
                   Name="videoListBox" 
                   SelectionChanged ="videoListBox_SelectionChanged"
                   ItemTemplate="{StaticResource imageTemplate}"
                   ItemsSource="{Binding ElementName=window1, Path=Thumbnails}" />
            </Grid>
            <media:MoviePlayerControl x:Name="moviePlayer" Grid.Row="1" />
        </Grid>
    </Window>
    
  4. Öffnen Sie die Codedatei mit dem Namen MainWindow.xaml.cs oder MainWindow.xaml.vb, und ersetzen Sie den automatisch generierten Code im Code-Editor durch den folgenden Code.

    Imports System
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Documents
    Imports System.Windows.Navigation
    Imports System.Windows.Shapes
    Imports System.Windows.Data
    Imports System.Windows.Media
    Imports System.Windows.Input
    
    Imports wfs = System.Windows.Forms
    Imports Microsoft.Win32
    
    Namespace VideoBrowser
    
        Class MainWindow
            Inherits Window
    
            Public Sub New()
                InitializeComponent()
            End Sub
    
            ' The list box on the form is 
            ' bound to this variable. 
            Private _thumbnails As New ThumbnailList()
    
            Public Property Thumbnails() As ThumbnailList
                Get
                    Return _thumbnails
                End Get
                Set(ByVal value As ThumbnailList)
                    _thumbnails = value
                End Set
            End Property
    
            Private Sub videoListBox_SelectionChanged( _
                ByVal sender As Object, _
                ByVal e As SelectionChangedEventArgs)
    
                moviePlayer.Close()
    
                ' Get the image name:
                Dim imageName As String = videoListBox.SelectedItem.ToString()
    
                ' Find the associated movie:
                Dim movieName As String = System.IO.Path.ChangeExtension(imageName, "wmv")
    
                ' Create a new URI for the selected movie, and play it:
                moviePlayer.PlayMovie(New Uri(movieName))
    
            End Sub
    
    
            Private Sub selectFolderButton_Click( _
                ByVal sender As Object, _
                ByVal e As RoutedEventArgs)
    
                Dim folderBrowser = New wfs.FolderBrowserDialog()
                folderBrowser.RootFolder = Environment.SpecialFolder.MyComputer
                If folderBrowser.ShowDialog() = wfs.DialogResult.OK Then
                    Thumbnails.FolderName = folderBrowser.SelectedPath
                End If
    
            End Sub
        End Class
    End Namespace
    
    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Input;
    
    using wfs = System.Windows.Forms;
    using Microsoft.Win32;
    
    namespace VideoBrowser
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            // The list box on the form is 
            // bound to this variable. 
            private ThumbnailList _thumbnails =
              new ThumbnailList();
    
            public ThumbnailList Thumbnails
            {
                get { return _thumbnails; }
                set { _thumbnails = value; }
            }
    
            private void videoListBox_SelectionChanged(
              object sender, SelectionChangedEventArgs e)
            {
                moviePlayer.Close();
    
                // Get the image name:
                String imageName =
                  videoListBox.SelectedItem.ToString();
    
                // Find the associated movie:
                string movieName = System.IO.Path.
                  ChangeExtension(imageName, "wmv");
    
                // Create a new URI for the selected movie, and play it:
                moviePlayer.PlayMovie(new Uri(movieName));
            }
    
            private void selectFolderButton_Click(object sender, RoutedEventArgs e)
            {
                var folderBrowser = new wfs.FolderBrowserDialog();
                folderBrowser.RootFolder = Environment.SpecialFolder.MyComputer;
                if (folderBrowser.ShowDialog() == wfs.DialogResult.OK)
                {
                    Thumbnails.FolderName = folderBrowser.SelectedPath;
                }
            }
        }
    }
    

Checkpoint

Sie können die Anwendung jetzt erstellen und ausführen. Klicken Sie auf die Schaltfläche Ordner auswählen..., und wechseln Sie zu einem Ordner, der WMV-Dateien und entsprechende JPG-Dateien enthält. Wenn Sie den Ordner ausgewählt haben, werden die JPG-Miniaturansichten im Listenfeld angezeigt. Klicken Sie auf eine der Miniaturansichten, und die entsprechende WMV-Datei wird im MediaElement wiedergegeben.

Festlegen von Stilen für die Anwendung

Die Anwendung VideoBrowser wird mit den Standardstilen gerendert. Sie können die Darstellung und das Verhalten der Anwendung ändern, indem Sie Stile erstellen und anwenden. Stile werden oft in einer separaten Ressourcendatei gespeichert.

So legen Sie Stile für die Anwendung fest

  1. Fügen Sie im Projektmappen-Explorer dem VideoBrowser-Projekt ein neues Ressourcenwörterbuch hinzu. Weitere Informationen finden Sie unter Exemplarische Vorgehensweise: Verwalten von Ressourcen im WPF-Projekt.

  2. Ersetzen Sie den automatisch generierten XAML-Code durch den folgenden XAML-Code.

        <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. Öffnen Sie MainWindow.xaml, und kommentieren Sie den folgenden XAML-Code nach dem Starttag des MainWindow-Elements aus.

    <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. Heben Sie die Auskommentierung des folgenden XAML-Codes auf.

    <!--<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. Klicken Sie in der Entwurfsansicht, um den XAML-Code in die Entwurfsoberfläche zu laden.

    Die neuen Stile werden für die Steuerelemente auf der Entwurfsoberfläche übernommen.

  6. Drücken Sie F5, um die Anwendung zu erstellen und auszuführen.

Siehe auch

Weitere Ressourcen

Migration und Interoperabilität

Arbeiten mit Steuerelementen im WPF-Designer