Wer wie ich mit Prism arbeitet, dabei aber nicht auf Ribbon verzichten möchte, nutzt einfach den Ribbon Region Adapter. Sowohl „WPF PRISM 4.0 and Ribbons“ als auch der Artikel „Creating View-Switching Applications with Prism 4“ auf codeproject.com bieten Informationen dazu. Problematisch wird es nur, wenn wie in meinem Fall auf VB.Net statt auf C# gesetzt wird. Um dennoch mit Ribbon arbeiten zu können, habe ich den RibbonRegionAdapter in VB.Net umgesetzt. Die wichtigsten Ausschnitte der Klasse sind im Folgenden erläutert.

Imports System.Windows
Imports System.Collections.Specialized
Imports Microsoft.Practices.Prism.Regions
Imports Microsoft.Windows.Controls.Ribbon

Public Class RibbonRegionAdapter
    Inherits RegionAdapterBase(Of Ribbon)

    Public Sub New(behaviorFactory As IRegionBehaviorFactory)
        MyBase.New(behaviorFactory)
    End Sub

Wie im Listing zu erkennen, wird Microsoft.Practices.Prism.Regions und Microsoft.Windows.Controls.Ribbon importiert. Die Klasse RibbonRegionAdapter erbt dabei von RegionAdapterBase aus Prism.Regions. Im Konstruktor von RibbonRegionAdapter wird der Konstruktor der Basisklasse aufgerufen, wobei die IRegionBehaviorFactory übergeben wird.

Protected Overrides Function CreateRegion() As Microsoft.Practices.Prism.Regions.IRegion
    Return New SingleActiveRegion
End Function

Die Funktion CreateRegion() kann nahezu identisch übernommen werden. Es müssen lediglich die VB.Net spezifischen Anpassungen vorgenommen werden.

Protected Overrides Sub Adapt(region As Microsoft.Practices.Prism.Regions.IRegion, 
  regionTarget As Microsoft.Windows.Controls.Ribbon.Ribbon)
    AddHandler region.Views.CollectionChanged, Sub(sender, e)
        Select Case e.Action
            Case NotifyCollectionChangedAction.Add
                For Each element As FrameworkElement In e.NewItems
                    regionTarget.Items.Add(element)
                Next
            Case NotifyCollectionChangedAction.Remove
                For Each elementLoopVariable As UIElement In e.OldItems
                    Dim element = elementLoopVariable
                    If regionTarget.Items.Contains(element) Then
                        regionTarget.Items.Remove(element)
                    End If
                Next
        End Select
    End Sub
End Sub

In der Methode Adapt() werden zwei Fälle unterschieden. Sollen neue Elemente hinzugefügt werden, wird für jedes neue Element die Methode Add() der Zielregion aufgerufen und das neue Element damit hinzugefügt. Sollen Elemente entfernt werden, so wird geprüft, ob sich das Element in der Zielregion befindet. Ist dies der Fall, wird es mit der Methode Remove() entfernt. Die Funktionalität unterscheidet sich nicht von der Version in C#. Es ist lediglich ein anderer Aufbau.

Ich hoffe so ein paar Leuten, die auf VB.Net angewiesen sind, helfen zu können. In einem der nächsten Artikel werde ich vermutlich auf die geheimnisvolle Variable KeepAlive von IRegionMemberLifetime eingehen.