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

发布于 2024-10-04 04:26:59 字数 2352 浏览 3 评论 0原文

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

System.Windows.Data Error: 40 : BindingExpression path error: 'IsDropDownOpen' property not find on 'object' ''RibbonContentPresenter '(名称='PART_ContentPresenter')'。 BindingExpression:Path=IsDropDownOpen; DataItem='RibbonContentPresenter'(名称='PART_ContentPresenter');目标元素是“RibbonButton”(名称=“”); target property is 'NoTarget' (type 'Object')

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

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

兮颜 2024-10-11 04:26:59

绑定错误位于 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>

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>
回忆躺在深渊里 2024-10-11 04:26:59

我使用 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>

I have Styled the RibbonButton with a ControlTemplate and without the MultiDataTrigger as below:
This will not caused the binding errors.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文