簡體   English   中英

如何讓 WPF 的 ClipToBounds 工作?

[英]How can I get WPF's ClipToBounds to work?

我有一個應用程序,它在 WPF 的圖像 object 中顯示圖像。 該圖像包含在一個控件中,其 xaml 如下所示:

<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>

其中兩個控件包含在 window 的網格中,如下所示:

    <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:

    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;
                }
            }
        }
    }

一旦調用了該比例變換,圖像就不再包含在其 canvas 或網格選擇的邊界中。 本質上, ClipToBounds 被忽略了。 我怎樣才能讓這個變換注意 ClipToBounds?

Canvas 有點獨特,因為它不像其他元素那樣真正參與布局系統。 它基本上充當具有固定 position 子級的無限大小空間,因此通常完全忽略剪輯。 如果沒有看到更多代碼,我無法確定,但如果您想將剪裁應用於縮放的 object,則將縮放移動到不同的元素可能會滿足您的需求。 最簡單的做法是在您的 Canvas 周圍包裹一個邊框,然后將 ScaleTransform 應用到它上面。 邊框應該給你更好的剪裁行為。

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

上面的評論幫助我。 將一個 canvas 嵌套在另一個中,將ClipToBounds="True"添加到父級,並將嵌套的高度和寬度分別綁定到父級屬性。
這種方式消除了對父級執行轉換的需要。

<Canvas ClipToBounds="True" Name="Outer">
     <Canvas x:Name="Inner" 
         Height="{Binding ActualHeight, ElementName=Outer, Mode=OneWay}"
         Width="{Binding ActualWidth, ElementName=Outer, Mode=OneWay}" />
</Canvas>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM