在 ScrollViewer 中控制 Canvas 的大小

Control size of Canvas in ScrollViewer

我正在编写一个用于图像显示和交互的自定义​​控件。它需要的一些功能是缩放和平移以及绘制自定义感兴趣区域,即在显示帧的顶部绘制具有任意位置和大小的矩形。缩放和平移功能已完成并且运行良好,我在 C# 代码中使用 ScrollViewer、缩放变换和一些用于鼠标单击和移动的事件处理程序。

对于自定义选择功能,我想在框架顶部添加一个 canvas,因为这是我所知道的允许任意定位矩形的唯一方法。为了使 canvas 上的任何形状都可以映射到图像坐标,我当然需要 canvas 与图像完全对齐,因此大小和位置必须相同。我还希望图像继续调整为 window 调整大小,就像没有任何 canvas 一样。由于 Canvas 不会自动将自身调整为任何我想将其尺寸绑定到图像大小的东西(这是来自自定义控件的控件模板):

<ScrollViewer x:Name="scrollViewer" Grid.Column="0" Grid.Row="1" CanContentScroll="True" PanningMode="Both" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
  <Grid>
    <Image x:Name="screen" Panel.ZIndex="0" Cursor="Cross" Source="{TemplateBinding ColoredFrame}"/
    <Canvas x:Name="testCanvas" Panel.ZIndex="1" Background="Transparent" Width="{Binding ActualWidth, ElementName=screen}" Height="{Binding ActualHeight, ElementName=screen}"/>
    <Grid.LayoutTransform>
      <TransformGroup>
        <RotateTransform Angle="{Binding RotationAngle, RelativeSource={RelativeSource TemplatedParent}}"/>
        <ScaleTransform x:Name="scaleTransform" ScaleX="{Binding ZoomFactor, RelativeSource {RelativeSource TemplatedParent}}" ScaleY="{Binding ZoomFactor, RelativeSource={RelativeSource TemplatedParent}}"/>
      </TransformGroup>
    </Grid.LayoutTransform>
  </Grid>
</ScrollViewer>

但是,我遇到了奇怪的行为 - 当我将 canvas 的宽度和高度绑定到图像的 ActualWidth 和 ActualHeight 时,就像上面的代码一样,它会自动调整自己的大小仅在 大小增加时(当用户增加 window 的大小时)但在大小减小时不会。任何大小的增加都是永久性的,当再次减小 window 时,必须随着图像的大小滚动,而 canvas 永远不会减小。当我仅绑定一个维度(宽度或高度)并将另一个维度设置为常量值时,不会发生这种情况。绑定方式(单向/双向)也没有影响。

我可能遗漏了一些非常明显的东西,但我花了几个小时试图弄清楚这一点,但我不知所措。任何帮助将不胜感激。

据我所知 Canvas 没有合适的尺寸选择。我认为 Adorner 会完成您想要实现的目标。有关示例和其他信息,请查看此处:https://docs.microsoft.com/de-de/dotnet/framework/wpf/controls/adorners-overview

快乐编码 蒂姆