Edit this page

How to Use RadOutlookBar as a Container in Prism Application

This help article will show you how to use RadOutlookBar as a container for hosting views.

Start off by creating an empty Visual Studio solution. Call this solution OutlookBarAndPrism.

Then, add a Silverlight project and call it Shell.

Add references to:

  • Microsoft.Practices.Composite.dll
  • Microsoft.Practices.Composite.Presentation.dll
  • Microsoft.Practices.Composite.UnityExtensions.dll
  • Microsoft.Practice.Unity.dll

You can download the latest binaries from here. Further information on how to download and build prism can be found here.

Then, add references to:

  • Telerik.Windows.Controls.dll
  • Telerik.Windows.Controls.Navigation.dll

Delete MainPage.xaml(along with MainPage.xaml.cs), add a new folder called Views and add a UserControl called ShellView to the Views folder.

Open ShellView.xaml and add a RadOutlookBar control. Register the RadOutlookBar control with Prism’s RegionManager by giving it a RegionName. In this case, registration can happen in XAML by annotating a UIElement with a RegionName attached property.

XAML

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="300" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <!--xmlns:prism="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"-->
    <telerik:RadOutlookBar prism:RegionManager.RegionName="OutlookBarRegion" />
</Grid>

Once a region has been defined via XAML, it will automatically be registered at run time with RegionManager, one of the composition services registered by the bootstrapper. RegionManager is essentially a Dictionary where the key is the name of the region and the value is an instance of the IRegion interface.

Next, we need to add a bootstrapper class to the Shell project.

The Bootstrapper inherits UnityBootstrapper and is the starting point of every Prism application. Two common tasks need to be done every time a Bootstrapper is used:

  1. Create Shell

  2. Create Module Catalog

For the moment we will do just step 1.

C#

public void Initialize()
{
    // Register views here.
    this.regionManager.RegisterViewWithRegion("OutlookBarRegion", () =>
    {
        return new ModuleAView().OutlookBarItem;
    });
}

VB.NET

Public Sub Initialize()
    Me.regionManager.RegisterViewWithRegion("OutlookBarRegion", Function()
                                                                    Return New ModuleAView().OutlookBarItem
                                                                End Function)
End Sub

Now we have to actually run the bootstrapper. Go to App.xaml.cs and modify the Application_Startup event handler.

C#

private void Application_Startup(object sender, StartupEventArgs e)
{
    Bootstrapper bootstrapper = new Bootstrapper();
    bootstrapper.Run();
}

VB.NET

Private Sub Application_Startup(sender As Object, e As StartupEventArgs)
    Dim bootstrapper As New Bootstrapper()
    bootstrapper.Run()
End Sub

Now if you run the application in this state, you will get the following error.

This error is caused by the fact that currently there are no modules to display, so let’s add one.

Add a new Silverlight Class Library to the OutlookBarAndPrism solution and called it ModuleA.

Remove the Class1.cs file that is added by default.Add reference to Microsoft.Practices.Composite.dll and Microsoft.Practices.Unity.dll. Add a new class to the ModuleA class library and call it ModuleA.

It is not required that the class library and the newly added class have the same name.

Make ModuleA class implement the IModule interface. The IModule interface contains a method, void Initialize, which we will have to implement.

C#

public class ModuleA : IModule
{
    IUnityContainer container;
    IRegionManager regionManager;

    public ModuleA(IRegionManager regionManager, IUnityContainer container)
    {
        this.regionManager = regionManager;
        this.container = container;
    }

    public void Initialize()
    {
        // Register views here.
    }
}

VB.NET

Public Class ModuleA
    Implements IModule
    Private container As IUnityContainer
    Private regionManager As IRegionManager

    Public Sub New(regionManager As IRegionManager, container As IUnityContainer)
        Me.regionManager = regionManager
        Me.container = container
    End Sub

    Public Sub Initialize()
    End Sub
End Class

We will be back shortly with the implementation of the Initialize method.

Now, add a new folder to the ModuleA class library and call it Views. Add a new UserControl to the Views folder and call it ModuleAView. ModuleAView will contain a RadTreeView. Therefore, we need to add references to Telerik.Windows.Controls.dll and Telerik.Windows.Controls.Navigation.dll to ModuleA class library. This is how ModuleAView might look like:

XAML

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation">
    <Grid Background="White">
        <telerik:RadTreeView>
            <telerik:RadTreeViewItem Header="ModuleA Item 0">
                <telerik:RadTreeViewItem Header="ModuleA Item 0.1" />
            </telerik:RadTreeViewItem>
            <telerik:RadTreeViewItem Header="ModuleA Item 1">
                <telerik:RadTreeViewItem Header="ModuleA Item 1.1" />
            </telerik:RadTreeViewItem>
        </telerik:RadTreeView>
    </Grid>
</UserControl>

Now that we have our first view defined, we need to register it in the Initialize method.

C#

public void Initialized()
{
    // Register views here.
    this.regionManager.RegisterViewWithRegion("OutlookBarRegion", () =>
    {
        return new ModuleAView();
    });
}

VB.NET

Public Sub Initialized()
    ' Register views here.'
    Me.regionManager.RegisterViewWithRegion("OutlookBarRegion", Function()
                                                                    Return New ModuleAView()

                                                                End Function)
End Sub

If you remember, in the ShellView we registered the RadOutlookBar using prism:RegionManager.RegionName="OutlookBarRegion". That is why the first parameter in the RegisterViewWithRegion is called OutlookBarRegion.

Now let’s leave ModuleA for a bit and go back to the Bootstrapper class in Shell. So far, we have done only one of two necessary tasks:

  1. Create Shell (done)
  2. Create Module Catalog

Since we have added a module, let’s create a module catalog. First of all, add a reference to the ModuleA class library.

Then open the Bootstrapper class and override the GetModuleCatalog() method.

C#

protected override IModuleCatalog GetModuleCatalog()
{
    ModuleCatalog catalog = new ModuleCatalog();
    catalog.AddModule(typeof(ModuleA.ModuleA));
    return catalog;
}

VB.NET

Protected Overrides Function GetModuleCatalog() As IModuleCatalog
    Dim catalog As New ModuleCatalog()
    catalog.AddModule(GetType(ModuleA.ModuleA))
    Return catalog
End Function

So far, if you run the project you should get result similar to the one bellow:

Strangely, the RadOutlookBarItem has no header and the title is a .ToString() representation of the ModuleAView class. To fix that we can add an ItemHeader property to the ModuleAView user control.

C#

public ModuleAView()
{
    InitializeComponent();
    this.ItemHeader = "ModuleA";
}

public string ItemHeader { get; set; }

VB.NET

Public Sub New()
    InitializeComponent()
    Me.ItemHeader = "ModuleA"
End Sub

Public Property ItemHeader() As String
    Get
        Return m_ItemHeader
    End Get
    Set(value As String)
        m_ItemHeader = Value
    End Set
End Property
Private m_ItemHeader As String

Then, go to the RadOutlookBar’s definition in ShellView.xaml and add a DisplayMemberPath property pointing to Header.

XAML

<telerik:RadOutlookBar prism:RegionManager.RegionName="OutlookBarRegion" DisplayMemberPath="ItemHeader" />

Now, if you run the project, you will see that the RadOutlookBarItem has a header.

The last thing that needs to be done is to make the Title area display ModuleA as well. The fastest way to do this is to use the TextSearch class that is located in the Telerik.Windows.Controls namespace in Telerik.Windows.Controls.dll.

C#

public ModuleaView()
{
    this.InitializeComponent();
    this.ItemHeader = "ModuleA";
    Telerik.Windows.Controls.TextSearch.SetText(this, "ModuleA");
}

VB.NET

Public Sub New()
    Me.InitializeComponent()
    Me.ItemHeader = "ModuleA"
    Telerik.Windows.Controls.TextSearch.SetText(Me, "ModuleA")
End Sub

Now if you run the project, the output should be similar to the one bellow.

Another approach to this scenario is to insert an actual RadOutlookBarItem. What I mean by that is instead of having in ModuleAView.xaml:

XAML

<Grid Background="White">
    <telerik:RadTreeView>
        <telerik:RadTreeViewItem Header="ModuleA Item 0">
            <telerik:RadTreeViewItem Header="ModuleA Item 0.1" />
        </telerik:RadTreeViewItem>
        <telerik:RadTreeViewItem Header="ModuleA Item 0">
            <telerik:RadTreeViewItem Header="ModuleA Item 0.1" />
        </telerik:RadTreeViewItem>
    </telerik:RadTreeView>
</Grid>

You can add the RadTreeView as a content to a RadOutlookBarItem:

XAML

<Grid Background="White">
    <telerik:RadOutlookBarItem x:Name="outlookBarItem1" 
                               Title="Some Title"
                               Header="Some Item">
        <telerik:RadTreeView>
            <telerik:RadTreeViewItem Header="ModuleA Item 0">
                <telerik:RadTreeViewItem Header="ModuleA Item 0.1" />
            </telerik:RadTreeViewItem>
            <telerik:RadTreeViewItem Header="ModuleA Item 0">
                <telerik:RadTreeViewItem Header="ModuleA Item 0.1" />
            </telerik:RadTreeViewItem>
        </telerik:RadTreeView>
    </telerik:RadOutlookBarItem>
</Grid>

Now, instead of having an ItemHeader property, you can create a property of type RadOutlookBarItem and return a reference to outlookBarItem1:

C#

public ModuleAView()
{
    InitializeComponent();
}
public RadOutlookBarItem OutlookBarItem
{
    get
    {
        return this.outlookBarItem1;
    }
}

VB.NET

Public Sub New()
    InitializeComponent()
End Sub
Public ReadOnly Property OutlookBarItem() As RadOutlookBarItem
    Get
        Return Me.outlookBarItem1
    End Get
End Property

In the Initialize() method of ModuleA.cs we will use the previously created OutlookBarItem property:

C#

public void Initialize()
{
    // Register views here.
    this.regionManager.RegisterViewWithRegion("OutlookBarRegion", () =>
    {
        return new ModuleAView().OutlookBarItem;
    });
}

VB.NET

Public Sub Initialize()
    Me.regionManager.RegisterViewWithRegion("OutlookBarRegion", Function()
                                                                    Return New ModuleAView().OutlookBarItem
                                                                End Function)
End Sub

Remove DisplayMemeberPath from RadOutlookBar’s definition in ShellView.xaml and run the project. If you get the following error, then we are on the right track.

The reason for it is that whatever is defined in LayoutRoot of ModuleAView.xaml is a child of ModuleAView, but we are adding it to RadOutlookBar as well. Thus the problem, one and the same visual element cannot appear on more than one place in the visual tree of the application. To overcome this issue, in the constructor of ModuleAView we need to remove whatever is in LayoutRoot.

C#

public ModuleAView()
{
    InitializeComponent();
    this.LayoutRoot.Children.Clear();
}

public RadOutlookBarItem OutlookBarItem
{
    get
    {
        return this.outlookBarItem1;
    }
}

VB.NET

Public Sub New()
    InitializeComponent()
    Me.LayoutRoot.Children.Clear()
End Sub

Public ReadOnly Property OutlookBarItem() As RadOutlookBarItem
    Get
        Return Me.outlookBarItem1
    End Get
End Property

Now if you run the project, everything should be fine.