Bind my Ribbon UI to my data model

The recommended way to bind the Ribbon UI to a data model is to encapsulate the command and the state associated with each control into a data object that is used as the DataContext for that control. You can then apply an implicit Style to the control that binds individual properties on it to corresponding properties of the data object. Please look at the attached sample that emulates the Clipboard group in Microsoft Word.


The XAML markup for this group ends up being very succinct. Notice that the primary operation here is just to set the DataContext on each control.

        <ribbon:Ribbon x:Name="Ribbon">

            <ribbon:RibbonTab Header="Home" KeyTip="H" >

                <ribbon:RibbonGroup x:Name="Clipboard" DataContext="{x:Static data:WordModel.Clipboard}">

                    <ribbon:RibbonSplitButton DataContext="{x:Static data:WordModel.Paste}">

                        <ribbon:RibbonMenuItem DataContext="{x:Static data:WordModel.Paste}" />

                        <ribbon:RibbonMenuItem DataContext="{x:Static data:WordModel.PasteSpecial}" />

                        <ribbon:RibbonMenuItem DataContext="{x:Static data:WordModel.PasteAsHyperlink}" />


                    <ribbon:RibbonButton DataContext="{x:Static data:WordModel.Cut}" />

                    <ribbon:RibbonButton DataContext="{x:Static data:WordModel.Copy}" />

                    <ribbon:RibbonButton DataContext="{x:Static data:WordModel.FormatPainter}" />




The implicit Styles for these controls are specified in a ResourceDictionary along the ancestor lookup path.

        <Grid x:Name="LayoutRoot">


            <!-- RibbonControl -->

            <Style x:Key="RibbonControlStyle">

                <Setter Property="ribbon:RibbonControlService.Label"

                        Value="{Binding Label}" />

                <Setter Property="ribbon:RibbonControlService.LargeImageSource"

                        Value="{Binding LargeImage}" />

                <Setter Property="ribbon:RibbonControlService.SmallImageSource"

                        Value="{Binding SmallImage}" />

                <Setter Property="ribbon:RibbonControlService.ToolTipTitle"

                        Value="{Binding ToolTipTitle}" />

                <Setter Property="ribbon:RibbonControlService.ToolTipDescription"

                        Value="{Binding ToolTipDescription}" />

                <Setter Property="ribbon:RibbonControlService.ToolTipImageSource"

                        Value="{Binding ToolTipImage}" />

                <Setter Property="ribbon:RibbonControlService.ToolTipFooterTitle"

                        Value="{Binding ToolTipFooterTitle}" />

                <Setter Property="ribbon:RibbonControlService.ToolTipFooterDescription"

                        Value="{Binding ToolTipFooterDescription}" />

  <Setter Property="ribbon:RibbonControlService.ToolTipFooterImageSource"

                        Value="{Binding ToolTipFooterImage}" />



            <!-- RibbonButton -->

            <Style TargetType="{x:Type ribbon:RibbonButton}"

                   BasedOn="{StaticResource RibbonControlStyle}">

                <Setter Property="Command" Value="{Binding Command}" />


            <!-- RibbonToggleButton -->

            <Style TargetType="{x:Type ribbon:RibbonToggleButton}"

                   BasedOn="{StaticResource RibbonControlStyle}">

                <Setter Property="Command" Value="{Binding Command}" />

                <Setter Property="IsChecked" Value="{Binding IsChecked}" />





This pattern of factoring the visuals and the data helps maintain clean lines of separation between the View and the Model. It also helps scenarios such as moving tasks back and forth between the RibbonQuickAccessToolBar and the main Ribbon, where the same data is visualized multiple different places.


Read next post for learn what using a RibbonWindow buys you.