WPF功能区:DataTemplate导致BindingExpression路径错误

时间:2010-11-25 10:26:12

标签: c# wpf datatemplate ribbon

我使用WPF RibbonControl(2010年10月版)遇到了一个小问题。我的想法是将RibbonGroup的ItemsSource属性绑定到我的viewmodel,并使用DataTemplate根据需要创建RibbonButtons。这样可行,但是当您显示窗口时,它会导致绑定错误(每个按钮一个):

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')

这是一个代码片段,viewmodel被一个字符串数组替换,但问题是相同的:

<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>

同样,它可以工作,但绑定错误有点烦人。有没有办法摆脱它?

2 个答案:

答案 0 :(得分:3)

绑定错误位于RibbonControlsLibrary中RibbonButton的控件模板中。该样式定义了以下MultiDataTrigger,并在RibbonButton用作另一个控件的一部分时使用,如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>

答案 1 :(得分:1)

我使用ControlTemplate设置了RibbonButton并且没有MultiDataTrigger,如下所示: 这不会导致绑定错误。

<ribbon:RibbonWindow.Resources>

    <ControlTemplate x:Key="RibbonButtonTemplate" TargetType="{x:Type ribbon:RibbonButton}">
        <Grid x:Name="MainGrid" SnapsToDevicePixels="True">

            <Border x:Name="OuterBorder"
                CornerRadius="{TemplateBinding CornerRadius}"
                Background="{TemplateBinding Background}"
                BorderBrush="{TemplateBinding BorderBrush}"
                BorderThickness="{TemplateBinding BorderThickness}" 
                Margin="1,1,1,1"/>

            <Border x:Name="MiddleBorder"
                CornerRadius="{TemplateBinding CornerRadius}"
                Background="Transparent"
                BorderBrush="Transparent"
                BorderThickness="{TemplateBinding BorderThickness}" >
                <Border x:Name="InnerBorder"
                    Background="Transparent"
                    BorderBrush="Transparent"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}"
                    CornerRadius="{TemplateBinding CornerRadius}">
                    <StackPanel x:Name="StackPanel"
                            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                            VerticalAlignment="{TemplateBinding VerticalContentAlignment}">

                        <Image x:Name="PART_Image"
                           Source="{TemplateBinding LargeImageSource}"
                           Margin="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type ribbon:Ribbon}, 
                            ResourceId=LargeImageMargin}}"
                           RenderOptions.BitmapScalingMode="NearestNeighbor"
                           VerticalAlignment="Center"
                           HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" />

                        <Grid x:Name="GridText"
                          VerticalAlignment="Center"
                          HorizontalAlignment="Center">

                            <ribbon:RibbonTwoLineText x:Name="TwoLineText"
                                    Text="{TemplateBinding Label}"
                                    TextAlignment="Center"
                                    VerticalAlignment="Top"
                                    HorizontalAlignment="Center"
                                    LineHeight="13px"
                                    LineStackingStrategy="BlockLineHeight"
                                    HasTwoLines="{TemplateBinding ribbon:RibbonTwoLineText.HasTwoLines}"
                                    PathData="{TemplateBinding ribbon:RibbonTwoLineText.PathData}"
                                    PathFill="{TemplateBinding Foreground}"
                                    Margin="1,1,1,0" />
                        </Grid>
                    </StackPanel>
                </Border>
            </Border>


        </Grid>

        <ControlTemplate.Triggers>

            <!-- Large Variant -->
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=ControlSizeDefinition.ImageSize}" Value="Large">
                <Setter Property="MinWidth" Value="44"/>
                <Setter Property="Height" Value="66"/>
                <Setter TargetName="GridText" Property="MinHeight" Value="26" />
                <Setter TargetName="TwoLineText" Property="HasTwoLines" Value="True" />
            </DataTrigger>

            <!-- Medium or Small Variant -->
            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=ControlSizeDefinition.ImageSize}" Value="Small">
                <Setter Property="Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SmallImageSource}"/>
                <Setter TargetName="StackPanel" Property="HorizontalAlignment" Value="Left" />

                <Setter TargetName="PART_Image" Property="Margin" Value="2,2,2,2" />
                <Setter TargetName="PART_Image" Property="Source" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SmallImageSource}" />
                <Setter TargetName="PART_Image" Property="Width" Value="16" />
                <Setter TargetName="PART_Image" Property="Height" Value="16" />
                <Setter TargetName="PART_Image" Property="HorizontalAlignment" Value="Left" />

                <Setter TargetName="TwoLineText" Property="HorizontalAlignment" Value="Left" />
                <Setter TargetName="TwoLineText" Property="Margin" Value="1" />
                <Setter TargetName="StackPanel" Property="Orientation" Value="Horizontal" />
            </DataTrigger>


            <!-- IsMouseOver -->
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="OuterBorder" Property="Background" 
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverBackground}" />
                <Setter TargetName="OuterBorder" Property="BorderBrush" 
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=MouseOverBorderBrush}" />
                <Setter TargetName="InnerBorder" Property="BorderBrush"
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FocusedBorderBrush}" />
            </Trigger>

            <!-- IsFocused -->
            <Trigger Property="IsKeyboardFocused" Value="True">
                <Setter TargetName="OuterBorder" Property="Background" 
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FocusedBackground}" />
                <Setter TargetName="OuterBorder" Property="BorderBrush" 
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FocusedBorderBrush}" />
                <Setter TargetName="InnerBorder" Property="BorderBrush" 
                        Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=FocusedBorderBrush}"/>
            </Trigger>

        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style x:Key="RibbonButtonStyle" TargetType="{x:Type ribbon:RibbonButton}" >
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="CornerRadius" Value="2" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="HorizontalContentAlignment" Value="Center" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
        <Setter Property="MouseOverBorderBrush" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.MouseOverBorderBrush}" />
        <Setter Property="MouseOverBackground" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.MouseOverBackground}" />
        <Setter Property="PressedBorderBrush" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.PressedBorderBrush}" />
        <Setter Property="PressedBackground" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.PressedBackground}" />
        <Setter Property="FocusedBorderBrush" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.FocusedBorderBrush}" />
        <Setter Property="FocusedBackground" Value="{Binding RelativeSource={RelativeSource Self},Path=Ribbon.FocusedBackground}" />
        <Setter Property="Template" Value="{StaticResource RibbonButtonTemplate}" />
        <Setter Property="QuickAccessToolBarControlSizeDefinition">
            <Setter.Value>
                <ribbon:RibbonControlSizeDefinition ImageSize="Small" IsLabelVisible="False" />
            </Setter.Value>
        </Setter>

    </Style>

    <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}" 
                             Style="{StaticResource ResourceKey=RibbonButtonStyle}" />
    </DataTemplate>


</ribbon:RibbonWindow.Resources>