【问题标题】:WPF clipping even when no clipping is desired - how to turn it off?即使不需要剪辑,WPF 也会进行剪辑 - 如何将其关闭?
【发布时间】:2011-06-18 21:05:55
【问题描述】:

我需要从ListBox 中浮出一些内容,如DataTemplate 中为ListBox.ItemTemplate 指定的那样。我正在使用RenderTransform,但内容被剪裁在ListBox 边界上。 ClipToBounds 是整个可视化树的 False

我在某处读到 WPF 在内部执行一些剪辑,即使没有指定专用剪辑属性。我还发现使用Canvas 有时可以解决剪辑问题,但在这里没有帮助。

我该如何克服这个问题?这是我要修复的一些 XAML。请注意矩形的整个左侧部分丢失。

    <ListBox>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50">
                    <Rectangle.RenderTransform>
                        <TranslateTransform X="-50" />
                    </Rectangle.RenderTransform>
                </Rectangle>
            </DataTemplate>
        </ListBox.ItemTemplate>

        42
    </ListBox>

【问题讨论】:

    标签: wpf clipping


    【解决方案1】:

    ListBoxItemListBox 模板中的ScrollViewer 剪裁。要解决这个问题,我认为您需要从模板中删除 ScrollViewer,如果您需要滚动,可以将 ListBox 包装在 ScrollViewer

    <ScrollViewer HorizontalScrollBarVisibility="Auto"
                  VerticalScrollBarVisibility="Auto">
        <ListBox Margin="100,10,0,0">
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </ListBox.Template>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50">
                        <Rectangle.RenderTransform>
                            <TranslateTransform X="-50" />
                        </Rectangle.RenderTransform>
                    </Rectangle>
                </DataTemplate>
            </ListBox.ItemTemplate> 42
        </ListBox>
    </ScrollViewer>
    

    更新

    模板中的ScrollViewer 将生成一个ScrollContentPresenter,而GetLayoutClip 又具有以下GetLayoutClip

    protected override Geometry GetLayoutClip(Size layoutSlotSize)
    {
        return new RectangleGeometry(new Rect(base.RenderSize));
    }
    

    这个类是密封的,所以你不能从它派生来覆盖这个方法。你必须实现你自己的ScrollContentPresenter(例如MyScrollContentPresenter)和可能你自己的使用MyScrollContentPresenterScrollViewer才能使这个工作(如果你在这个方法中返回null我认为有些项目低于ListBox 的范围也可能变得可见)

    【讨论】:

    • 你看起来很准!但我需要 ScrollViewer 在它原来的位置。你知道ScrollVeiwer的内部实现有什么特别的地方让我很伤心吗?这是可以在派生类中覆盖的东西吗?我在某处读到 GetLayoutClip 是罪魁祸首,但我不能让它按我的方式工作。
    • @wpfwannabe:更新了我的答案。你说得对,GetLayoutClip 是问题所在。不幸的是,这一次它在一个密封类 (ScrollContentPresenter) 中,所以你不能从中派生。据我所知,要做到这一点需要做很多工作
    • 你的回答太棒了!很大的帮助!非常感谢!同时,我通过ListBoxItem 的拆分以不同的方式重新排列了我的布局,这使我可以在ListBox 中显示浮动内容,因此我不再需要整个ScrollViewer malarkey。大多数时候,人们可以为同一问题找到不同的解决方案。这次我不得不更改我的很多模板以使事情按预期工作,但这似乎比创建我自己的ScrollViewer 要容易得多。再次感谢!
    • @wpfwannabe:没问题 :) 是的,您的新解决方案似乎是一个更好的方法!祝你好运
    【解决方案2】:

    我在解决这个问题时偶然发现了一个解决方案。如果在样式模板中将 ScrollViewer 的 Horizo​​ntalScrollMode 和 VerticalScrollMode 更改为“Disabled”,它将分别停止各个方向的剪辑。

    编辑:可能不适用于 WPF。我使用 UWP 应用进行了测试。有问题的字段是:

    ScrollViewer.Horizo​​ntalScrollMode="已禁用"

    ScrollViewer.VerticalScrollMode="已禁用"

    【讨论】:

    • WPF中没有Horizo​​ntalScrollMode这样的属性
    • 抱歉,应该提到,我已经对其进行了测试,并让它在 UWP 应用程序中运行,并且我认为它适用于 WPF。猜猜不是。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 2023-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    相关资源
    最近更新 更多