You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF:缩放含边界Canvas及图形适配大Canvas且保留描边厚度

Solution: Use ScaleTransform on the Bounding Canvas

Great question! The key here is to scale your entire "bounding Canvas" (and its contents) without altering stroke thickness—something ViewBox ruins by scaling every visual element, including strokes. Here's a clean, low-maintenance approach that avoids tedious per-Path tweaks:

Step 1: Calculate the Scaling Ratio

First, figure out how much to scale your original Canvas to fit the larger target:

  • For uniform scaling (e.g., target is exactly double the original size), use a 1:1 ratio for width and height.
  • For non-uniform target sizes, use the smaller ratio (e.g., if target is 400x300 and original is 160x160, ratio = min(400/160, 300/160) = 1.875) to prevent clipping and preserve aspect ratio.

Step 2: Apply the ScaleTransform

Wrap your original bounding Canvas inside the larger target, then add a LayoutTransform (affects layout) or RenderTransform (visual-only scaling) to the original. This scales the entire canvas and its contents proportionally, while keeping Stroke.Thickness fixed.

Here's a modified example:

<!-- Larger target Canvas -->
<Canvas Height="320" Width="320" Background="LightGray">
  <!-- Original bounding Canvas with scaling applied -->
  <Canvas Height="160" Width="160" Background="Red">
    <Canvas.LayoutTransform>
      <!-- Scale by 2x to fit the 320x320 target -->
      <ScaleTransform ScaleX="2" ScaleY="2" />
    </Canvas.LayoutTransform>
    <Path Stroke="#000000" StrokeThickness="1"
          Data="M27.9,108 c0,0 25,-63 48.5,-51.5 s34.5,64.5 68.5,37">
    </Path>
  </Canvas>
</Canvas>

Step 3 (Optional): Center the Scaled Canvas

To center the scaled canvas in the target, combine the ScaleTransform with a TranslateTransform using a TransformGroup:

<Canvas.LayoutTransform>
  <TransformGroup>
    <ScaleTransform ScaleX="1.875" ScaleY="1.875" />
    <!-- Shift to center: (TargetSize - ScaledOriginalSize)/2 -->
    <TranslateTransform X="50" Y="0" />
  </TransformGroup>
</Canvas.LayoutTransform>

Why This Works

  • The ScaleTransform preserves the relative position of the Path inside its bounding Canvas—no need to edit any Path data.
  • Stroke.Thickness is a fixed pixel value, so it won’t be scaled along with the geometry.
  • You only modify the parent Canvas, not every individual Path—far cleaner than setting Stretch=Fill on each element.

Dynamic Scaling (Code-Behind)

If you need to adjust scaling dynamically (e.g., when the target resizes), calculate the ratio and apply the transform in code:

// Get original and target dimensions
double originalWidth = originalCanvas.Width;
double originalHeight = originalCanvas.Height;
double targetWidth = targetCanvas.ActualWidth;
double targetHeight = targetCanvas.ActualHeight;

// Calculate proportional scaling ratio
double scaleX = targetWidth / originalWidth;
double scaleY = targetHeight / originalHeight;
double scaleRatio = Math.Min(scaleX, scaleY);

// Apply the scale transform
originalCanvas.LayoutTransform = new ScaleTransform(scaleRatio, scaleRatio);

// Optional: Center the scaled canvas
double offsetX = (targetWidth - originalWidth * scaleRatio) / 2;
double offsetY = (targetHeight - originalHeight * scaleRatio) / 2;
var scaleTransform = (ScaleTransform)originalCanvas.LayoutTransform;
scaleTransform.CenterX = originalWidth / 2;
scaleTransform.CenterY = originalHeight / 2;

内容的提问来源于stack exchange,提问作者Thins12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:13:10