XAML/WPF缩放到画布上的特定区域
本文关键字:区域 WPF 缩放 XAML | 更新日期: 2023-09-27 18:18:54
所以我有一个有2列的网格的WPF窗口。在第一列中,我有一个画布,我要将SVG图像呈现给它。这个画布被重新调整为与图像相同的大小(因此没有进行变换),并且假设图像比屏幕小得多,因此不需要滚动查看器-我将其称为左侧画布。
在第二列中,我有另一个位于Viewbox内的画布,相同的SVG也被渲染到该画布,并且假设SVG图像大小大于Viewbox固定大小。Viewbox会重新调整画布的大小以适应它——尽管它似乎没有对画布进行任何变换,也没有改变画布的宽度或高度,这里有一些其他的神奇之处——但是很好,它工作了。
我们的想法是,用户可以绘制矩形左边的画布,将代表一个放大区域,然后正确的画布放大,使矩形适合Viewbox包含画布,适合我的意思是没有裁剪或拉伸/镇压任何放大区域,如果它是一个风景肖像Viewbox放大区域,缩放的区域将会见双方Viewbox留下空间的顶部和底部是好。
我认为这将是直接的,因为没有变换应用于任何画布,他们都有相同的宽度和高度(即使一些魔术从Viewbox是使正确的一个更小)。我现在是这样做的:
找到中心点:
centreX = Canvas.GetLeft(zoomAreaRect) + (zoomAreaRect.Width / 2);
centreY = Canvas.GetTop(zoomAreaRect) + (zoomAreaRect.Height / 2);
查找刻度量:
double scale;
if(zoomAreaRect.Width > zoomAreaRect.Height)
{
scale = RightCanvas.Width / zoomAreaRect.Width;
}
else
{
scale = RightCanvas.Height / zoomAreaRect.Height;
}
然后使用缩放变换,使用centreX和centreY作为变换的中心,并在变换上缩放scaleX和scaleY。
现在这显然不起作用,因为我需要在计算比例时以某种方式考虑Viewbox大小,我只是不确定如何做到这一点。有人能帮忙吗?
更新:
我已经取消了Viewbox,因为这会使事情复杂化。因此,右边的画布也是正常大小,但包含在具有固定宽度和高度的边界内。目的是放大缩放区域,直到它适合边框。
右边的XAML:
<Border Name="ContainingBorder"
Grid.Column="1"
MaxWidth="295"
MaxHeight="487"
Height="487">
<Border.Clip>
<RectangleGeometry Rect="0.5, 0.5, 295, 487"/>
</Border.Clip>
<Canvas Name="RightCanvas"/>
</Border>
我已经设法放大了正确的数量,它只是没有放大到正确的中心。我只是使用宽高比作为比例的数量,似乎工作:
double ratioX = ContainingBorder.AcctualWidth / zoomAreaRect.Width;
double ratioY = ContainingBorder.AcctualHeight / zoomAreaRect.Height;
double scale = ratioX < ratioY ? ratioX : ratioY;
知道怎么求出中心x和y吗?上面的centreX和centreY计算似乎不能正常工作
我不确定我是否完全理解了你的问题。也许粘贴xaml代码会有帮助。
可能你可以使用画布的"margin"属性:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!--clip to bounds for hide parts of the canvas-->
<Viewbox ClipToBounds="True">
<!--set margin negatively to zoom out of the viewbox size-->
<Canvas Margin="0,0,-100,-100" Width="200" Background="Red" Height="200">
<Rectangle Width="100" Height="100" Fill="Gray"/>
</Canvas>
</Viewbox>
</Grid>
也许你可以用视觉刷来解决这个问题:
<Window x:Class="ZoomViewBoxTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="700">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Viewbox Width="700" Height="300">
<Canvas x:Name="LeftCanvas" Width="600" Background="Red" Height="600">
<!--drawing Rectangle simulates your zoom area-->
<Rectangle x:Name="DrawingRectange" Width="100" Height="150" Fill="Green" Canvas.Left="200" Canvas.Top="300"></Rectangle>
<Rectangle Width="200" Height="200" Fill="Gray" Canvas.Left="250" Canvas.Top="350"/>
</Canvas>
</Viewbox>
<Viewbox Grid.Column="1">
<Rectangle Width="{Binding ElementName=DrawingRectange,Path=Width}" Height="{Binding ElementName=DrawingRectange,Path=Height}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=LeftCanvas}" Stretch="None" >
<VisualBrush.Viewbox>
<!-- X = DrawingRectangle.X / LeftCanvas.Width
Y = DrawingRectangle.X / LeftCanvas.Height
Width = DrawingRectangle.Width / LeftCanvas.Width
Height = DrawingRectangle.Height / LeftCanvas.Height-->
<Rect X="0.333" Y="0.5" Width="0.1666" Height="0.25"></Rect>
</VisualBrush.Viewbox>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>
</Viewbox>
</Grid>
VisualBrush的Viewbox必须绑定到DrawingRectangle的实际值(在后面的代码中或通过转换器)