如何让 WPF 的 ClipToBounds 工作? [英] How can I get WPF's ClipToBounds to work?

查看:36
本文介绍了如何让 WPF 的 ClipToBounds 工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,它在 WPF 中的 Image 对象内显示图像.该图像包含在其 xaml 如下所示的控件中:

I have an application that displays an image inside of an Image object in WPF. The image is contained in a control whose xaml looks like:

<UserControl x:Class="MyProgram.NativeImageDisplay"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="UserControl_Loaded">
    <Canvas Name="border" Background="Black" >
        <Image Name="image" StretchDirection="Both" Stretch="Uniform" ClipToBounds="True"
                SnapsToDevicePixels="True" RenderOptions.BitmapScalingMode="HighQuality"></Image>
    </Canvas>
</UserControl>

其中两个控件包含在窗口的网格中,如下所示:

Two of these controls are contained in a grid in a window, like so:

    <Grid  Grid.Row="2" Name="DisplayCanvas">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <l:NativeImageDisplay x:Name="imageDisplay2" Grid.Column="1" ClipToBounds="True"/>
        <l:NativeImageDisplay x:Name="imageDisplay" Grid.Column="0" ClipToBounds="True"/>           
    </Grid>

从这里开始,我一直认为剪辑是真实的.

I'm calling clipping to be true all the way through here.

用户可以使用鼠标上的滚动按钮放大图像,并最终调用图像上的 ScaleTransform:

The user can zoom on the image by using the scroll button on the mouse, and that ultimately calls a ScaleTransform on the image:

    private void image_MouseWheel(object sender, MouseWheelEventArgs e)
    {
        if (!thumbnail)
        {
            TransformGroup transformGroup = (TransformGroup)border.RenderTransform;
            ScaleTransform transform = (ScaleTransform)transformGroup.Children[0];

            double oldScaleX = transform.ScaleX;
            double oldScaleY = transform.ScaleY;

            double zoom = e.Delta;
            transform.ScaleX += zoom / 10000;
            transform.ScaleY += zoom / 10000;
            if (transform.ScaleX > maxZoom || transform.ScaleY > maxZoom)
            {
                transform.ScaleX = maxZoom;
                transform.ScaleY = maxZoom;
            }
            if (transform.ScaleX < minZoom || transform.ScaleY < minZoom)
            {
                transform.ScaleX = minZoom;
                transform.ScaleY = minZoom;
            }
            Point thePoint = e.GetPosition(border);
            transform.CenterY = 0;
            transform.CenterX = 0;

            foreach (UIElement child in border.Children)
            {
                if (child is Anchor)
                {
                    TransformGroup group = (TransformGroup)child.RenderTransform;
                    ScaleTransform t = (ScaleTransform)group.Children[0];
                    t.ScaleX *= oldScaleX / transform.ScaleX;
                    t.ScaleY *= oldScaleY / transform.ScaleY;
                }
            }
        }
    }

一旦调用该缩放变换,图像就不再包含在其画布或网格选择的边界中.本质上,ClipToBounds 被忽略了.我怎样才能让这个转换关注 ClipToBounds?

Once that scale transform is called, the image is no longer contained in the boundary of its canvas or the grid selection. Essentially, ClipToBounds is being ignored. How can I make this transform pay attention to ClipToBounds?

推荐答案

Canvas 的独特之处在于它不像其他元素那样真正参与布局系统.它基本上充当具有固定位置子项的无限大小空间,因此通常完全忽略裁剪.如果没有看到更多代码,我无法确定,但是如果您想将裁剪应用于缩放对象,将缩放移动到不同的元素可能会做您想要的.最简单的做法是在 Canvas 周围包裹一个 Border,然后将 ScaleTransform 应用于它.边框应该为您提供更好的剪切行为.

Canvas is kind of unique in that it doesn't really participate in the layout system like other elements. It basically acts as an infinite size space with fixed position children so generally ignores clipping completely. I can't tell for sure without seeing more of the code but if you want to apply the clipping to the scaled object moving the scaling to a different element might do what you want. The simplest thing to do would be to wrap a Border around your Canvas and apply the ScaleTransform to that instead. The Border should give you better clipping behavior.

<Border x:Name="border" Background="Black" ClipToBounds="True">
    <Canvas x:Name="imageHost">
    ...
    </Canvas>
</Border>

这篇关于如何让 WPF 的 ClipToBounds 工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆