WPF ToolBar 和 StackPanel 在裁剪时自动变为 ClipToBounds="True"

WPF ToolBar and StackPanel turns ClipToBounds="True" automatically when cropped

我需要在 WPF 中显示工具栏边界外的一些子项目(光标悬停时工具栏上的按钮会变大)。

Image 1: Right panel behavior: ClipToBounds="False"

当 ClipToBounds="False" 并且所有按钮在工具栏中都有一个位置时一切正常。当面板的一部分被 window 的边缘裁剪并且某些按钮没有位置时,就会出现问题。在这种情况下,ToolBar 和 StackPanel 会自动将 ClipToBounds 属性 切换为 "True" 并开始裁剪子项。

Image 2: Wrong panel behavior: ClipToBounds snaps to "True"

我可以禁用此行为吗?或者除了在最宽的透明容器上绘制按钮外别无他法?

我的解决方案(只是将工具栏分成几层):

<Window x:Class="ZoomBarMockup.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="200" Width="300">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>

        <Rectangle Grid.Row="0" Fill="#CCC"/>
        <Rectangle Grid.Row="2" Fill="#CCC"/>

        <!-- Decorative toolbar background strip -->
        <Border Grid.Row="1">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Color="#FFF" Offset="0"/>
                    <GradientStop Color="#DDD" Offset="1"/>
                </LinearGradientBrush>
            </Border.Background>            
        </Border>

        <!-- Wide transparent panel with negative margin -->
        <StackPanel Grid.Row="1" Orientation="Horizontal" ClipToBounds="False"
                    Height="50" Margin="0 -10 0 -10">
            <Ellipse Fill="Orange" Height="50" Width="50" Margin="5 0"/>
            <Ellipse Fill="Orange" Height="50" Width="50" Margin="5 0"/>
            <Ellipse Fill="Orange" Height="50" Width="50" Margin="5 0"/>
            <Ellipse Fill="Orange" Height="50" Width="50" Margin="5 0"/>
            <Ellipse Fill="Orange" Height="50" Width="50" Margin="5 0"/>
        </StackPanel>

    </Grid>
</Window>

您可以禁用面板的默认裁剪行为。但是为了做到这一点,您必须扩展现有面板之一或实现您自己的面板:

class NoClipStackPanel : StackPanel
{
    protected override Geometry GetLayoutClip(Size layoutSlotSize)
    {
        return null;
    }
}

检查 this answer 以获取有关不同剪辑方法的更多详细信息。