In diesem Teil der Windows Presentation Foundation 4.5 Serie wird das in in WPF 4.5 integrierte Ribbon-Steuerelement genauer beleuchtet. Bereits in den Versionen davor gab es die Möglichkeit das externe Microsoft Ribbon Control zu verwenden. Dies gehört der Vergangenheit an.

Bevor wir zu einem einfachen Beispiel (eine beispielhafte Nachbildung der Windows Live Writer Oberfläche) kommen, werden ein paar grundlegende Informationen zum Steuerelement beschrieben.

Dieses Blog bietet viele weitere Artikel, Tipps und Tricks zum Thema Windows Presentation Foundation (WPF).

Die einzelnen Bestandteile

Das Ribbon-Steuerelement ist aus mehreren Bestandteilen zusammengesetzt, die jeweils einzeln konfiguriert werden können. Die nachfolgende Grafik gibt einen kurzen Überblick.Bestandteile des Ribbon-Steuerelementes

Das Application Menu selbst besteht wiederum aus mehreren Teilen, die nachfolgend visuell dargestellt sind:

Bestandteile des Ribbon Application Menu

Voraussetzungen

Um das Steuerelement nutzen zu können, muss eine Referenz auf die Assembly System.Windows.Controls.Ribbon.dll hinzugefügt werden.

Einbinden der Assembly System.Windows.Controls.Ribbon.dll

Wie im Screenshot schon zu sehen ist, wird das Target Framework vom .NET Framework 4.5 Client Profile auf .NET Framework 4.5 umgestellt, da diese Assembly im Client Profile nicht enthalten ist.

Im nächsten Schritt ist ein XML-Namespace zu definieren, über den in weiterer Folge auf das Steuerelement (und dessen Bestandteile) zugegriffen werden kann:

<Window x:Class="DevTyr.Wpf45.RibbonDemo.MainWindow"
        xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
        Title="DevTyr WPF 4.5 Demo - Ribbon" Height="350" Width="525">
    <DockPanel>

    </DockPanel>
</Window>

Das RibbonWindow

Anstatt der Verwendung der herkömmlichen Window-Klasse (wie im obigen Markup) kann auf ein RibbonWindow zurück gegriffen werden. Dadurch wird eine bessere Unterstützung des Ribbon-Steuerelementes geboten. So wird beispielsweise die Schnellzugriffsleiste in die Titelleiste integriert und liefert für den Benutzer ein wesentlich besseres Bild ab. Natürlich kann aber auch ein herkömmliches Fenster verwendet werden.

Hier die Verwendung mit einem herkömmlichen Fenster:

Ribbon Steuerelelement mit Standard Windows Klasse

Und nun zum Vergleich der Einsatz der Klasse  RibbonWindow:

Ribbon Steuerelelement in RibbonWindow

Beispiel

Im nächsten Schritt sehen wir uns das bereits oben angesprochene Beispiel an und versuchen den Windows Live Writer in einigen Teilen nachzubauen. Dazu ist es wichtig zu wissen, wie die einzelnen Elemente miteinander verschachtelt werden können. Dabei hilfreich ist die folgende Infografik:

WPF Ribbon-Control Infografik

Mit dieser Information können nun die Inhalte des Ribbon-Elementes einfach aufgefüllt werden. Elemente wie RibbonButton und RibbonMenuButton bieten zudem die Eigenschaften SmallImageSource und LargeImageSource an. Darüber können sowohl Grafiken für eine kleine bzw. für eine große Darstellung definiert werden. Im Hintergrund arbeitet hier die Enumeration ImageSize. Diese besitzt die Werte Small (16×16 Pixel), Large (32×32 Pixel, Standardeinstellung) und Collapsed. Die angegebenen Grafiken werden nun auf diese Enumeration hin geprüft. Kann keine Zuordnung stattfinden, wird eine Grafik angezeigt.

Besonders wichtig ist dies, wenn man das Default-Layout des Ribbon-Elementes steuern/beeinflussen möchte. Mehr dazu in Ribbon Layout and Resizing.

Nachfolgend nun das gesamte XAML-Markup für dieses Beispiel. Die Screenshots dazu wurden bereits weiter oben gezeigt.

<ribbon:RibbonWindow x:Class="DevTyr.Wpf45.RibbonDemo.MainWindow"
        xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon"
        Title="DevTyr WPF 4.5 Demo - Ribbon" Height="350" Width="525">

    <DockPanel LastChildFill="True">

        <ribbon:Ribbon DockPanel.Dock="Top">
            <Ribbon.QuickAccessToolBar>
                <RibbonQuickAccessToolBar>
                    <RibbonButton Label="Save"
                                  SmallImageSource="Resources/Images/saveHS.png"/>
                    <RibbonButton Label="Undo"
                                  SmallImageSource="Resources/Images/112_ArrowReturnLeft_Blue_16x16_72.png"/>
                    <RibbonButton Label="Redo"
                                  SmallImageSource="Resources/Images/112_ArrowReturnRight_Blue_16x16_72.png"/>
                </RibbonQuickAccessToolBar>
             </Ribbon.QuickAccessToolBar>

            <Ribbon.ApplicationMenu>
                <RibbonApplicationMenu SmallImageSource="Resources/Images/ApplicationMenu.png">
                    <RibbonApplicationMenuItem Header="Neuer Beitrag" 
                                               ImageSource="Resources/Images/NewEntry.png"/>
                    <RibbonApplicationMenuItem Header="Lokalen Entwurf öffnen" 
                                               ImageSource="Resources/Images/OpenLocalEntry.png"/>                    
                    <RibbonApplicationMenuItem Header="Aktuellen Beitrag öffnen" 
                                               ImageSource="Resources/Images/OpenEntry.png"/>
                    <RibbonApplicationMenuItem Header="Speichern"
                                               ImageSource="Resources/Images/Save.png"/>
                    <RibbonApplicationMenuItem Header="Lokalen Beitrag löschen"/>
                    <RibbonApplicationMenuItem Header="Veröffentlichen"/>
                    <RibbonApplicationMenuItem Header="Drucken"/>
                    <RibbonApplicationMenuItem Header="Optionen"/>
                    <RibbonApplicationMenuItem Header="Info"/>
                    <RibbonApplicationMenuItem Header="Beenden"/>
                    <RibbonApplicationMenu.FooterPaneContent>
                        <RibbonButton Label="Exit"
                                      SmallImageSource="Resources/Images/305_Close_48x48_72.png"
                                      HorizontalAlignment="Right"/>
                    </RibbonApplicationMenu.FooterPaneContent>
                    <RibbonApplicationMenu.AuxiliaryPaneContent>
                        <RibbonGallery CanUserFilter="False"
                                       ScrollViewer.VerticalScrollBarVisibility="Auto">
                            <RibbonGalleryCategory Background="Transparent"
                                                   MaxColumnCount="1">
                                <RibbonGalleryItem Content="Aktualisierung einer Datenbindung verzögern"/>
                                <RibbonGalleryItem Content="Informationen einer BindingExpression beziehen"/>
                                <RibbonGalleryItem Content="Bindung an statische Eigenschaften"/>
                                <RibbonGalleryItem Content="Neue Funktionen der Klasse VirtualizingPanel"/>
                                <RibbonGalleryItem Content="Das Ribbon-Steuerelement"/>
                            </RibbonGalleryCategory>
                        </RibbonGallery>
                    </RibbonApplicationMenu.AuxiliaryPaneContent>
                </RibbonApplicationMenu>
            </Ribbon.ApplicationMenu>
            <Ribbon.HelpPaneContent>
                <RibbonButton Content="Hilfe"
                              SmallImageSource="Resources/Images/Help.png"/>
            </Ribbon.HelpPaneContent>
            <RibbonTab Header="Start">
                <RibbonGroup Header="Zwischenablage">
                    <RibbonComboBox IsEditable="False" 
                                    SmallImageSource="Resources/Images/paste.png">
                        <RibbonGallery SelectedValue="Einfügen"
                                       SelectedValuePath="Content"
                                       MaxColumnCount="1">
                            <RibbonGalleryCategory>
                                <RibbonGalleryItem Content="Einfügen"/>
                                <RibbonGalleryItem Content="Inhalte einfügen ..."/>
                            </RibbonGalleryCategory>
                        </RibbonGallery>
                    </RibbonComboBox>
                    <RibbonButton Label="Ausschneiden"
                                  SmallImageSource="Resources/Images/CutHS.png"/>
                    <RibbonButton Label="Kopieren"
                                  SmallImageSource="Resources/Images/CopyHS.png"/>
                </RibbonGroup>
                <RibbonGroup Header="Veröffentlichen">
                    <RibbonButton Label="Veröffentlichen"
                                  LargeImageSource="Resources/Images/publish.png"/>
                    <RibbonButton Label="Entwurf im Blog veröffentlichen"
                                  SmallImageSource="Resources/Images/draft.png"/>
                </RibbonGroup>
            </RibbonTab>

            <RibbonTab Header="Einfügen">
                <!-- Place tab elements here -->
            </RibbonTab>
                <!-- Place tab elements here -->
            <RibbonTab Header="Blogkonto">

            </RibbonTab>

        </ribbon:Ribbon>

        <StackPanel>
            <!-- Placeholder for content -->
        </StackPanel>
    </DockPanel>
</ribbon:RibbonWindow>

Commanding, MVVM etc.

Die Elemente, die Aktionen auslösen (RibbonButton, RibbonApplicationMenuItem usw.) bieten die Eigenschaften Command, CommandBindings, CommandParameter und CommandTarget an. Dadurch kann die notwendige Funktionalität gut in einer Implementierung der Klasse ICommand gekapselt werden. Ein Anbieten über ein ViewModel ist natürlich möglich und sinnvoll.

Weitere Informationen zum Thema Commanding, Datenbindung, MVVM finden sich hier.

Eine Beschreibung aller Klassen, Eigenschaften etc. findet sich im MSDN.

Download Beispiel

Ich möchte darauf hinweisen, dass hier eine Vorabversion behandelt wird und Änderungen bis zur finalen Version möglich – und sogar wahrscheinlich – sind.

Über den Autor

Norbert Eder

Ich bin ein leidenschaftlicher Softwareentwickler und Fotograf. Mein Wissen und meine Gedanken teile ich nicht nur hier im Blog, sondern auch in Fachartikeln und Büchern.

5 Kommentare

Hinterlasse einen Kommentar