首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎样才能让WPF的ClipToBounds工作?

我怎样才能让WPF的ClipToBounds工作?
EN

Stack Overflow用户
提问于 2011-07-14 04:02:52
回答 2查看 22.4K关注 0票数 7

我有一个在WPF中显示image对象内部图像的应用程序。该图像包含在一个控件中,该控件的xaml如下:

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
    <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>

我在这里一直调用裁剪为真。

用户可以通过使用鼠标上的滚动按钮来缩放图像,最终调用图像上的ScaleTransform:

代码语言:javascript
复制
    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呢?

EN

回答 2

Stack Overflow用户

发布于 2011-07-14 07:56:54

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

代码语言:javascript
复制
<Border x:Name="border" Background="Black" ClipToBounds="True">
    <Canvas x:Name="imageHost">
    ...
    </Canvas>
</Border>
票数 21
EN

Stack Overflow用户

发布于 2017-05-03 21:27:05

上面的评论对我很有帮助。将一个画布嵌套在另一个画布中,将ClipToBounds="True"添加到父画布,并将嵌套的高度和宽度分别绑定到父属性。

这种方式消除了对父对象执行转换的需要。

代码语言:javascript
复制
<Canvas ClipToBounds="True" Name="Outer">
     <Canvas x:Name="Inner" 
         Height="{Binding ActualHeight, ElementName=Outer, Mode=OneWay}"
         Width="{Binding ActualWidth, ElementName=Outer, Mode=OneWay}" />
</Canvas>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6684904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档