WPF ribbon, change main content when ribbontab is selected

I guess there is a more simpler way to do it. I have done it like this:

<Frame NavigationUIVisibility="Hidden" x:Name="FrmMainFrame" DockPanel.Dock="Bottom"/>

And in your code behind:

mainWindowView.RibMain.SelectionChanged += RibMain_SelectionChanged;

void RibMain_SelectionChanged(object sender,  System.Windows.Controls.SelectionChangedEventArgs e)
    {
        var tab = this.mainWindowView.RibMain.SelectedItem as RibbonTab;
        if (tab.Header.Equals("Explorer"))
        {
            mainWindowView.FrmMainFrame.Navigate(explorerController.View());
        }
        else
            mainWindowView.FrmMainFrame.NavigationService.Navigate(new Uri("http://www.google.com/"));
    }

Ill preface by saying I doubt this is the best way to do this.

This is my style for RibbonTab notice IsSelected is bound to IsSelected in The view model

  <!-- RibbonTab -->
        <Style TargetType="{x:Type ribbon:RibbonTab}">
            <Setter Property="ContextualTabGroupHeader" Value="{Binding ContextualTabGroupHeader}" />
            <Setter Property="Header" Value="{Binding Header}" />
            <Setter Property="ItemsSource" Value="{Binding GroupDataCollection}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected}" />
        </Style>

This is view model code

    public bool IsSelected
    {
        get
        {
            return _isSelected;
        }

        set
        {
            if (_isSelected != value)
            {
                _isSelected = value;
                OnPropertyChanged(new PropertyChangedEventArgs("IsSelected"));
            }
        }
    }
    private bool _isSelected;

In the constructor for the TabViewModel I take a parameter for the ViewModel of the content

    public TabData(ISelectedContentTab content)
        : this(content.DisplayName)
    {
        _selectedContent = content;
    }

    private ISelectedContentTab _selectedContent;

Then I used an ItemsControl to display the selected content in my xaml

  <ItemsControl Grid.Row="1" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch" 
                  ItemsSource="{Binding ElementName=ribbon,Path=SelectedItems}" 
                  ItemTemplate="{StaticResource ContentControlTemplate}" />

And the ContentControlTemplate I have is

 <DataTemplate x:Key="ContentControlTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <ContentControl Grid.Row="0" VerticalAlignment="Stretch" Height="Auto" VerticalContentAlignment="Stretch" Content="{Binding SelectedContent}" />
            </Grid>
        </DataTemplate>

Also make sure you have a datatemplate pointing your content to a view

Hope this helps.


The idea is to have content below ribbon stacked in layers, (like in Photoshop or any other graphical editor) and show only layer you need this moment. Just bind Visibility of your layer to IsSelected property of desired tab

MainGrid here is a container for layers (which are Grids too):

    <Grid x:Name="MainGrid">
        <Grid Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=ribbonTab2}">
            <Image x:Name="ImgMain" Source="x.jpg"/>
        </Grid>
        <Grid Visibility="{Binding IsSelected, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=ribbonTab1}">
            <Image x:Name="ImgXtra" Source="y.jpg"/>
       </Grid>
    </Grid>

Add <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> in resources.

...and you don't need any code at all!