是什么让我的自定义 ContextMenu 抛出 System.Windows.Data 错误:4?

问题描述 投票:0回答:1

我制作了一个自定义 WPF

ContextMenu
,以在菜单顶部或底部的条带中显示按钮,就像 Windows 11 资源管理器上下文菜单中的复制/粘贴按钮一样。

一切正常,但在调试输出窗口中我收到以下错误:

System.Windows.Data 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', 祖先等级='1''。 BindingExpression:Path=HorizontalContentAlignment; 数据项=空;目标元素是“MenuItem”(名称=“”);目标财产 是“HorizontalContentAlignment”(类型“HorizontalAlignment”)

System.Windows.Data 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', 祖先等级='1''。 BindingExpression:Path=VerticalContentAlignment; 数据项=空;目标元素是“MenuItem”(名称=“”);目标财产 是“VerticalContentAlignment”(类型“VerticalAlignment”)

我能做些什么来让这些消失吗?我什至尝试过为

MenuItem
定义自定义样式和模板,但肯定不会尝试找到
ItemsControl
来获取
HorizontalContentAlignment
VerticalContentAlignment
属性,那么这是从哪里来的呢?

这是我的自定义的 XAML

ContextMenu
:

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        xmlns:controls="clr-namespace:Laila.Shell.Controls">
    
        <Style TargetType="{x:Type controls:ContextMenu}">
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Grid.IsSharedSizeScope" Value="true" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type controls:ContextMenu}">
                        <Border Padding="3" x:Name="PART_Menu" Opacity="0" BorderBrush="#999999" BorderThickness="1" 
                                Background="#F0F0F0" Margin="0,0,6,6" UseLayoutRounding="True" SnapsToDevicePixels="True">
                            <Border.Triggers>
                                <EventTrigger RoutedEvent="Rectangle.Loaded">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Menu" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Border.Triggers>
                            <Border.Effect>
                                <DropShadowEffect BlurRadius="3" Color="Black" ShadowDepth="3" Opacity="0.5" />
                            </Border.Effect>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
    
                                <Border x:Name="borderTop" Grid.Row="0" Background="#dfdfdf" Padding="2" Visibility="Visible">
                                    <StackPanel Orientation="Horizontal" x:Name="PART_ButtonsTop" />
                                </Border>
                                <ScrollViewer Grid.Row="1" x:Name="PART_ScrollViewer"
                                              HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
                                    <ItemsPresenter Margin="0,0,0,1" x:Name="PART_ItemsPresenter" />
                                </ScrollViewer>
                                <Border x:Name="borderBottom" Grid.Row="2" Background="#dfdfdf" Padding="2" Visibility="Visible">
                                    <StackPanel Orientation="Horizontal" x:Name="PART_ButtonsBottom" />
                                </Border>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="ShowButtonsTopOrBottom" Value="Bottom">
                                <Setter Property="Visibility" TargetName="borderTop" Value="Collapsed" />
                            </Trigger>
                            <Trigger Property="ShowButtonsTopOrBottom" Value="None">
                                <Setter Property="Visibility" TargetName="borderTop" Value="Collapsed" />
                            </Trigger>
                            <Trigger Property="ShowButtonsTopOrBottom" Value="Top">
                                <Setter Property="Visibility" TargetName="borderBottom" Value="Collapsed" />
                            </Trigger>
                            <Trigger Property="ShowButtonsTopOrBottom" Value="None">
                                <Setter Property="Visibility" TargetName="borderBottom" Value="Collapsed" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>

编辑:这些是我的菜单项的样式和模板:

        <SolidColorBrush x:Key="Menu.BorderBrush" Color="#999999"/>
        <SolidColorBrush x:Key="Menu.Background" Color="#F0F0F0"/>
        <SolidColorBrush x:Key="Menu.Foreground" Color="Black"/>
        <SolidColorBrush x:Key="MenuItem.Highlighted.BorderBrush" Color="#26A0DA"/>
        <SolidColorBrush x:Key="MenuItem.Highlighted.Background" Color="#C0DDEB"/>
        <SolidColorBrush x:Key="MenuItem.Highlighted.Foreground" Color="Black"/>
        <SolidColorBrush x:Key="MenuItem.Disabled.Foreground" Color="Gray"/>
        <Style x:Key="{x:Static MenuItem.SeparatorStyleKey}" TargetType="{x:Type Separator}">
            <Setter Property="Margin" Value="-10,0,0,0" />
        </Style>
        <Style TargetType="{x:Type Menu}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="{StaticResource Menu.Foreground}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Menu}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" 
                                Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" 
                                SnapsToDevicePixels="true">
                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
            <Grid SnapsToDevicePixels="true">
                <Border x:Name="Bg" BorderThickness="1" Background="Transparent" />
                <Grid Height="22">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="MenuItemCheckColumnGroup" Width="Auto"/>
                        <ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
                        <ColumnDefinition Width="4"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="37"/>
                        <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
                        <ColumnDefinition Width="17"/>
                    </Grid.ColumnDefinitions>
                    <Border x:Name="GlyphPanel" Height="20" Margin="1" Visibility="Collapsed" Width="22">
                        <Image x:Name="Glyph" Width="16" Height="16" Source="pack://application:,,,/Laila.Shell;component/Images/check16.png" />
                    </Border>
                    <ContentPresenter Grid.Column="1" x:Name="Icon" Height="16" Width="16" ContentSource="Icon" Margin="4,1,1,1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                    <ContentPresenter Grid.Column="3" ContentSource="Header" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <TextBlock Grid.Column="5" Margin="{TemplateBinding Padding}" VerticalAlignment="Center" Text="{TemplateBinding InputGestureText}"/>
                </Grid>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon" Value="{x:Null}">
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsCheckable" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Hidden"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Disabled.Foreground}"/>
                    <Setter Property="Opacity" TargetName="Glyph" Value="0.30"/>
                    <Setter Property="Opacity" TargetName="Icon" Value="0.30"/>
                </Trigger>
                <Trigger Property="IsPressed" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuContent, TypeInTargetAssembly={x:Type FrameworkElement}}" TargetType="{x:Type ContentControl}">
            <Border Padding="3" x:Name="PART_Menu" Opacity="0" BorderBrush="{StaticResource Menu.BorderBrush}" 
                    BorderThickness="1" Background="{StaticResource Menu.Background}" Margin="0,0,6,6">
                <Border.Triggers>
                    <EventTrigger RoutedEvent="Rectangle.Loaded">
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Menu" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Border.Triggers>
                <Border.Effect>
                    <DropShadowEffect BlurRadius="3" Color="Black" ShadowDepth="3" Opacity="0.5" />
                </Border.Effect>
                <ScrollViewer x:Name="PART_ScrollViewer"
                              HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
                    <ContentPresenter />
                </ScrollViewer>
            </Border>
        </ControlTemplate>
        <ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
            <Grid SnapsToDevicePixels="true">
                <Border x:Name="Bg" Background="{TemplateBinding Background}" BorderThickness="1">
                    <StackPanel Orientation="Horizontal">
                        <ContentPresenter x:Name="Icon" ContentSource="Icon" Margin="4,0,6,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                        <Image x:Name="GlyphPanel" Width="16" Height="16" Source="pack://application:,,,/Laila.Shell;component/Images/check16.png" Margin="7,0,0,0" Visibility="Collapsed" VerticalAlignment="Center" />
                        <ContentPresenter ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" 
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </StackPanel>
                </Border>
                <Popup x:Name="PART_Popup" AllowsTransparency="true" Focusable="false" HorizontalOffset="1" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" VerticalOffset="-1">
                    <Border>
                        <ContentControl x:Name="SubMenuBorder" IsTabStop="false" Template="{DynamicResource {ComponentResourceKey ResourceId=SubmenuContent, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                            <ScrollViewer x:Name="PART_ScrollViewer"
                                          HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
                                <Grid RenderOptions.ClearTypeHint="Enabled">
                                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="true" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                                </Grid>
                            </ScrollViewer>
                        </ContentControl>
                    </Border>
                </Popup>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon" Value="{x:Null}">
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsKeyboardFocused" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Disabled.Foreground}"/>
                    <Setter Property="Opacity" TargetName="GlyphPanel" Value="0.30"/>
                    <Setter Property="Opacity" TargetName="Icon" Value="0.30"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
            <Grid SnapsToDevicePixels="true">
                <Border x:Name="Bg" BorderThickness="1" Background="Transparent"/>
                <DockPanel>
                    <ContentPresenter x:Name="Icon" ContentSource="Icon" Margin="4,0,6,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                    <Image x:Name="GlyphPanel" Width="16" Height="16" Source="pack://application:,,,/Laila.Shell;component/Images/check16.png" Margin="7,0,0,0" Visibility="Collapsed" VerticalAlignment="Center" />
                    <ContentPresenter ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                </DockPanel>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon" Value="{x:Null}">
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsKeyboardFocused" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Disabled.Foreground}"/>
                    <Setter Property="Opacity" TargetName="GlyphPanel" Value="0.30"/>
                    <Setter Property="Opacity" TargetName="Icon" Value="0.30"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <Geometry x:Key="RightArrow">M 0,0 L 4,3.5 L 0,7 Z</Geometry>
        <ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
            <Grid SnapsToDevicePixels="true">
                <Border x:Name="Bg" BorderThickness="1" Background="Transparent"/>
                <Grid Height="22">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="MenuItemCheckColumnGroup" Width="Auto"/>
                        <ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/>
                        <ColumnDefinition Width="4"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="37"/>
                        <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
                        <ColumnDefinition Width="17"/>
                    </Grid.ColumnDefinitions>
                    <Border x:Name="GlyphPanel" BorderBrush="#CDD3E6" BorderThickness="1" Background="#E6EFF4" CornerRadius="3" Height="20" Margin="1" Visibility="Collapsed" Width="22">
                        <Image x:Name="Glyph" Width="16" Height="16" Source="pack://application:,,,/Laila.Shell;component/Images/check16.png" />
                    </Border>
                    <ContentPresenter Grid.Column="1" x:Name="Icon" Height="16" Width="16" ContentSource="Icon" Margin="4,1,1,1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/>
                    <ContentPresenter Grid.Column="3" ContentSource="Header" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <TextBlock Grid.Column="5" Margin="{TemplateBinding Padding}" VerticalAlignment="Center" Text="{TemplateBinding InputGestureText}" Visibility="Collapsed"/>
                    <Path Grid.Column="6" Data="{StaticResource RightArrow}" Fill="{TemplateBinding Foreground}" Margin="4,0,0,0" VerticalAlignment="Center"/>
                </Grid>
                <Popup x:Name="PART_Popup" AllowsTransparency="true" Focusable="false" HorizontalOffset="-2" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-3">
                    <ContentControl x:Name="SubMenuBorder" IsTabStop="false" Template="{DynamicResource {ComponentResourceKey ResourceId=SubmenuContent, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                        <ScrollViewer x:Name="PART_ScrollViewer"
                                      HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto">
                            <Grid RenderOptions.ClearTypeHint="Enabled">
                                <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="true" Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                            </Grid>
                        </ScrollViewer>
                    </ContentControl>
                </Popup>
            </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon" Value="{x:Null}">
                    <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
                </Trigger>
                <Trigger Property="IsCheckable" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Hidden"/>
                </Trigger>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsKeyboardFocused" Value="true">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Highlighted.Foreground}"/>
                    <Setter Property="Background" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.Background}"/>
                    <Setter Property="BorderBrush" TargetName="Bg" Value="{StaticResource MenuItem.Highlighted.BorderBrush}" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="false">
                    <Setter Property="Foreground" Value="{StaticResource MenuItem.Disabled.Foreground}"/>
                    <Setter Property="Opacity" TargetName="GlyphPanel" Value="0.30"/>
                    <Setter Property="Opacity" TargetName="Icon" Value="0.30"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
.net wpf vb.net wpf-controls wpf-core
1个回答
0
投票

显然这是由默认的

MenuItem
样式引起的,该样式尚未适应,因为我只是为不同类型的
ControlTemplate
重新定义了
MenuItem

我通过将其添加到我的应用程序范围样式中来摆脱这些消息:

    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="HorizontalContentAlignment" Value="Left"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>
© www.soinside.com 2019 - 2024. All rights reserved.