在 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
快乐编码
蒂姆
我正在编写一个用于图像显示和交互的自定义控件。它需要的一些功能是缩放和平移以及绘制自定义感兴趣区域,即在显示帧的顶部绘制具有任意位置和大小的矩形。缩放和平移功能已完成并且运行良好,我在 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
快乐编码 蒂姆