Search code examples
c#wpfdatatemplateribbon

WPF Ribbon: DataTemplate causes BindingExpression path error


I've run into a small problem using the WPF RibbonControl (October 2010 version). My idea was to bind the ItemsSource property of a RibbonGroup to my viewmodel, and use a DataTemplate to create RibbonButtons as needed. This works, but it causes a binding error (one for each button) when you show the window:

System.Windows.Data Error: 40 : BindingExpression path error: 'IsDropDownOpen' property not found on 'object' ''RibbonContentPresenter' (Name='PART_ContentPresenter')'. BindingExpression:Path=IsDropDownOpen; DataItem='RibbonContentPresenter' (Name='PART_ContentPresenter'); target element is 'RibbonButton' (Name=''); target property is 'NoTarget' (type 'Object')

Here is a code fragment, the viewmodel is replaced by an array of strings, but the issue is the same:

<ribbon:RibbonWindow x:Class="WpfRibbonApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" x:Name="RibbonWindow" Width="640" Height="480" >

    <ribbon:RibbonWindow.Resources>
        <x:Array x:Key="buttonArray" Type="sys:String">
            <sys:String>Button 1</sys:String>
            <sys:String>Button 2</sys:String>
            <sys:String>Button 3</sys:String>
            <sys:String>Button 4</sys:String>
            <sys:String>Button 5</sys:String>
            <sys:String>Button 6</sys:String>
        </x:Array>
        <DataTemplate x:Key="buttonTemplate">
            <ribbon:RibbonButton Label="{Binding}"  />
        </DataTemplate>        
    </ribbon:RibbonWindow.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <ribbon:Ribbon>
            <ribbon:RibbonTab Header="Tab1">
                <ribbon:RibbonGroup Header="Group1"
                    ItemsSource="{StaticResource buttonArray}" 
                    ItemTemplate="{StaticResource buttonTemplate}"
                />
            </ribbon:RibbonTab>
        </ribbon:Ribbon>         
    </Grid>
</ribbon:RibbonWindow>

Again, it works, but the binding error is a bit annoying. Is there any way to get rid of it?


Solution

  • The binding error is in the control template for the RibbonButton within the RibbonControlsLibrary. The style has the following MultiDataTrigger defined and is used when the RibbonButton is used as part of another control, like the RibbonSplitButton.

    <MultiDataTrigger>
        <MultiDataTrigger.Conditions>
            <Condition Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsDropDownOpen}" Value="True" />
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="False" />
            <Condition Binding="{Binding Path=HighContrast, Source={x:Static shell:SystemParameters2.Current}}" Value="True" />
        </MultiDataTrigger.Conditions>
        <Setter TargetName="OuterBorder" Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" />
    </MultiDataTrigger>