WPF 菜单 - 允许在禁用的菜单项中启用特定控件

WPF Menu - Allow specific control to be enabled inside disabled menuitem

我有一个绑定到 collection 模型的菜单。 MenuItem 命令绑定到模型命令。

我重新定义了 SubMenuItem 控件模板以在其中添加一个 ToggleButton。 此 ToggleButton 允许用户将 MenuItem 指定为“收藏夹”。我希望此 ToggleButton 始终处于启用状态。

 <ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}" TargetType="{x:Type MenuItem}">
    <Grid x:Name="PART_Conteneur" Background="Transparent">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" SharedSizeGroup="Star" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <ToggleButton x:Name="PART_StarButton" Style="{DynamicResource VerticalToolBarMenuStarToggleButtonStyle}" VerticalAlignment="Center" Margin="2,0,0,0" />
        <Border x:Name="Border" BorderThickness="1" Grid.Column="1" Padding="0,2,0,2">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Icon" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut" />
                    <ColumnDefinition Width="13" />
                </Grid.ColumnDefinitions>
                
                <ContentPresenter x:Name="Icon" Margin="6,0,6,0" VerticalAlignment="Center" Grid.Column="0" ContentSource="Icon" Width="20" />
                <ContentPresenter x:Name="HeaderHost" Grid.Column="1" ContentSource="Header" RecognizesAccessKey="True" VerticalAlignment="Center" />
                <TextBlock x:Name="InputGestureText" Grid.Column="2" Text="{TemplateBinding InputGestureText}" Margin="5,2,0,2" DockPanel.Dock="Right" />
            </Grid>
        </Border>
    </Grid>
    
    <ControlTemplate.Triggers>
        <Trigger Property="ButtonBase.Command" Value="{x:Null}" />
        <Trigger Property="Icon" Value="{x:Null}">
            <Setter TargetName="Icon" Property="Visibility" Value="Hidden" />
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
            <Setter Property="Background" TargetName="Border" Value="{DynamicResource ItemSelectedBrushKey}" />
            <Setter Property="BorderBrush" TargetName="Border">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF888888" Offset="0" />
                        <GradientStop Color="Transparent" Offset="1" />
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Opacity" Value="{DynamicResource DisableOpacity}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

当 MenuItem 被禁用时(Command CanExecute returns False),ToggleButton 也被禁用。

如何才能只启用 ToggleButton?

编辑:

我设法通过在将包含切换按钮的 TopLevelHeader 模板弹出窗口中添加一个新的 ItemsControl 来满足我的需求:

<ControlTemplate x:Key="VerticalToolBarMenuTopLevelHeaderTemplate" TargetType="{x:Type MenuItem}">
    <Border x:Name="Border">
        <Grid>
            <ContentPresenter Margin="6,3,20,3" ContentSource="Header" RecognizesAccessKey="True" HorizontalAlignment="Right" />
            <Popup x:Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Fade" StaysOpen="True">
                <Border x:Name="SubmenuBorder" SnapsToDevicePixels="True" BorderThickness="1" Background="{DynamicResource ToolBarPopupBackgroundBrushKey}" 
                        BorderBrush="{DynamicResource PopupBorderBrushKey}">
                    <ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Auto">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <ItemsControl ItemsSource="{Binding }">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Grid Height="25">
                                            <ToggleButton x:Name="PART_StarButton" Style="{DynamicResource VerticalToolBarMenuStarToggleButtonStyle}" VerticalAlignment="Center" Margin="2,0,0,0" />
                                        </Grid>                                            
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                            <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.Column="1" />
                        </Grid>                            
                    </ScrollViewer>
                </Border>
            </Popup>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsSuspendingPopupAnimation" Value="true">
            <Setter TargetName="Popup" Property="PopupAnimation" Value="None" />
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
            <Setter TargetName="Border" Property="BorderBrush" Value="Transparent" />
            <Setter Property="Background" TargetName="Border" Value="{DynamicResource ItemSelectedBrushKey}" />
        </Trigger>
        <Trigger SourceName="Popup" Property="AllowsTransparency" Value="True">
            <Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0,0,4,4" />
            <Setter TargetName="SubmenuBorder" Property="Padding" Value="0,0,0,3" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Opacity" Value="{DynamicResource DisableOpacity}" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

不,你不能这样做。 当 CanExecute returns 为 false 时,IsEnabled 属性 将采用相同的值。 IsEnabled = false 不仅禁用元素本身,还禁用嵌套在其中的所有内容。 此行为在 UIElement 中定义,无法更改。