This project is read-only.
Project Description
A RegionAdapter for the Ribbon native WPF control for the PRISM composite WPF application block.

This adapter supports the following:

  • Merge RibbonTabs and ContextualTabGroups
    • also merge RibbonGroups
  • Merge QuickAccessToolBar
  • Merge ApplicationMenu
  • handle sorting/ordering via attached property
  • detect identical tabls/ribbongroups via their Header property or an attached MergeKey property (the attached-property has priority)
  • detaches the merged elements from their old parent into the main ribbon, preserving the DataContext of each element

New with Version 0.20:

  • removing/unmerging

New with Version 0.11:

  • Merge any control which derives from ItemsControl, such as ContextMenu, ListBox, ListView, etc.
    • Register the MergingItemsControlRegionAdapter for these controls

Install via nuget:

install-package Prism.RibbonRegionAdapter

Quick-Start

  1. register the adapter in the Bootstrapper's ConfigureRegionAdapterMappings method:
    • mappings.RegisterMapping(typeof(Ribbon), ServiceLocator.Current.GetInstance<Prism.RibbonRegionAdapter.RibbonRegionAdapter>());
  2. add a "root" ribbon into which all other ribbons are merged and make it a region:
  3. in each module, which will extend the ribbon, add a UserControl and make it's root element a ribbon control
  4. in the module's Initialize method, register the module-ribbon with the region
    • _regionManager.RegisterViewWithRegion(ShellRegions.Ribbon, typeof(Views.Ribbon));

Affecting merge-order

Use the UIElementExtension.MergeOrder attached-property on any RibbonTab, RibbonGroup, or Ribbon-Item to affect the merge position

Affecting matching

Use the UIElementExtension.MergeKey attached-property on any RibbonTab, or RibbonGroup to uniquely identify it, when the corresponding Header property should not be used for matching.

Example Root Ribbon

<Ribbon prism:UIElementExtension.MergeOrder="10"
        x:Name="MainMenu" x:FieldModifier="protected internal"
        prism:RegionManager.RegionName="{x:Static loc:ShellRegions.MainMenu}">
  <RibbonTab Header="General"
             prism:UIElementExtension.MergeKey="{x:Static loc:MainMenuMergeKeys.GeneralTab}"
             prism:UIElementExtension.MergeOrder="10">
    <RibbonGroup Header="Group 1">
      <RibbonButton Label="Group1.Button1 (Main)" />
    </RibbonGroup>
    <RibbonGroup Header="Group 2"
                 prism:UIElementExtension.MergeKey="{x:Static loc:MainMenuMergeKeys.GeneralTabGroup2}">
      <RibbonButton Label="Group2.Button1 (Main)" />
      <RibbonButton Label="Group2.Button2 (Main)" />
    </RibbonGroup>
  </RibbonTab>
  <RibbonTab Header="Last Tab"
             prism:UIElementExtension.MergeKey="{x:Static loc:MainMenuMergeKeys.LastTab}"
             prism:UIElementExtension.MergeOrder="{x:Static sys:Double.MaxValue}">
  </RibbonTab>
</Ribbon>

Example Module-Ribbon

<UserControl x:Class="TestApplication.Module1.Ribbon"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:prism="http://www.codeplex.com/prism"
             xmlns:loc="clr-namespace:TestApplication"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
  <Ribbon x:Name="MainMenu" x:FieldModifier="protected internal">
    <RibbonTab Header="Module1 Tab">
    </RibbonTab>
    <RibbonTab Header="General (to be merged)"
                 prism:UIElementExtension.MergeKey="{x:Static loc:MainMenuMergeKeys.GeneralTab}"
                 prism:UIElementExtension.MergeOrder="10">
      <RibbonGroup Header="Group 1b">
        <RibbonButton Label="Group1b.Button1 (Module1)" />
        <RibbonButton Label="Group1b.Button2 (Module1)" />
      </RibbonGroup>
      <RibbonGroup Header="Group 2"
                     prism:UIElementExtension.MergeKey="{x:Static loc:MainMenuMergeKeys.GeneralTabGroup2}">
        <RibbonButton Label="Group2.Button1 (Module1, 10)" prism:UIElementExtension.MergeOrder="10" />
        <RibbonButton Label="Group2.Button2 (Module1, 99999)" prism:UIElementExtension.MergeOrder="99999" />
      </RibbonGroup>
      <RibbonGroup Header="Group 3">
        <RibbonButton Label="Group3.Button1 (Module1)" />
        <RibbonButton Label="Group3.Button2 (Module1)" />
        <RibbonButton Label="Group3.Button3 (Module1)" />
      </RibbonGroup>
    </RibbonTab>
  </Ribbon>
</UserControl>

Merging other ItemControl based controls, such as a ContextMenu

First create the context-menu (can be empty, but can also contain initial items) and apply the RegionManager.RegionName attached-property:
<TextBox.ContextMenu>
  <ContextMenu prism:RegionManager.RegionName="{x:Static loc:ShellRegions.EditorContextMenu}">
    <MenuItem Header="Item 1" />
    <MenuItem Header="Item 2">
      <MenuItem Header="Item 2.1" />
      <MenuItem Header="Item 2.2" />
    </MenuItem>
    <Separator />
    <MenuItem Header="Item 3" />
  </ContextMenu>
</TextBox.ContextMenu>

Next create the menu-extensions in the modules (to be able to use the designer, it's best to create UserControls and use it's ContextMenu property):
<UserControl.ContextMenu>
  <ContextMenu>
    <MenuItem Header="B1 (Module1)" Command="{Binding HelloCommand}" />
    <MenuItem Header="B2 override (Module1)" 
              prism:UIElementExtension.MergeKey="B2 (Main)"
              Command="{Binding HelloCommand}">
      <MenuItem Header="B2.1 (Module1)" Command="{Binding HelloCommand}" />
    </MenuItem>
    <MenuItem Header="B3 (Module1) (10)" 
              prism:UIElementExtension.MergeOrder="10"
              Command="{Binding HelloCommand}" />
  </ContextMenu>
</UserControl.ContextMenu>

Then register it with the region:
class Module1 : IModule
{
  private readonly IRegionManager _regionManager;

  public Module1(IRegionManager regionManager)
  {
    _regionManager = regionManager;
  }

  public void Initialize()
  {
    _regionManager.RegisterViewWithRegion(ShellRegions.EditorContextMenu, GetContextMenu);
  }

  private object GetContextMenu()
  {
    var cmv = ServiceLocator.Current.GetInstance<EditorContextMenuView>();
    cmv.ContextMenu.DataContext = cmv.DataContext;
    return cmv.ContextMenu;
  }
}

See the included sample-application for usage-details.

Last edited Mar 8, 2015 at 2:53 PM by uTILLIty, version 12