介绍:
我已将SVG
导出为XAML
,并将其转换为带有大量路径的画布。
将该画布设置为简单自动生成窗口的主要内容后,图像被剪裁,因为它比主窗口的客户区域大。
我通过实现平移来解决了这个问题。
由于我计划稍后调整缩放,因此我在Canvas的XAML中添加了虚拟的ScaleTransform
,并将其RenderTransformOrigin更改为0.5, 0.5
(以便我可以围绕图像中心缩放)。
当窗口加载时,我希望图像居中,因此我将该画布放在Viewbox内,经过调整几个属性后,似乎工作正常。
问题:
由于我更改了Canvas的RenderTransformOrigin,我无法弄清楚可以限制平移量的数学方法。
即使Viewbox是主窗口的内容,我也无法获取主窗口客户区域的尺寸(Viewbox会调整大小以适应其内容)。这使我的任务更加困难。
我的解决方案:
似乎没有其他方法可以获取主窗口的客户区矩形,除了使用P/Invoke
和GetClientRect
WinAPI调用。
还有一种方法是通过查询SystemParametersInfo来获取非客户端度量,例如边框和标题栏,但这是一个可能因应用主题等原因而失败的估计值。
我还没有尝试使用P/Invoke
,因为我目前拒绝这样做。必须有比这更好的解决方案!这条路应该是我的最后选择,也是我纯粹出于绝望而做出的选择。
我已经尝试过自己寻找替代方法,但失败了。
我尝试使用TransformToAncestor(...).Transformtobounds(..)
进行计算,但也失败了。
问题:
如何限制平移,使图像在用户拖动过多时不会从主窗口消失?
我将接受替代方案。提交的代码是一个经验不足、自学的初学者的尝试,所以我接受建设性的批评和建议。
相关信息:
为了让这篇文章尽可能简短,我只提供相关的XAML和“代码后台”片段如下。完整代码已经粘贴在Pastebin上,并且可以在本文底部找到。
相关的XAML片段:
<Window x:Class="TestZaMapu.MainWindow"
Name="GlavniProzor"
WindowStartupLocation="CenterScreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525"
MouseLeftButtonDown="GlavniProzor_MouseLeftButtonDown"
MouseLeftButtonUp="GlavniProzor_MouseLeftButtonUp"
MouseMove="GlavniProzor_MouseMove"
LostMouseCapture="GlavniProzor_LostMouseCapture">
<Viewbox
Name="surface"
Stretch="UniformToFill"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Background="Blue"
x:Name="svg4306"
Width="494.44705"
Height="510.55356"
<!-- needed in the future, for zooming around center-->
RenderTransformOrigin="0.5, 0.5">
<!--Unknown tag: metadata-->
<Canvas.RenderTransform>
<TransformGroup>
<!-- I intend to experiment with scaling in the future, so I added the below part -->
<ScaleTransform ScaleX="1" ScaleY="1"/>
<!-- I have used dependency properties for translation -->
<TranslateTransform X="{Binding TranslationFactorX, ElementName=GlavniProzor, Mode=TwoWay}" Y="{Binding TranslationFactorY, ElementName=GlavniProzor, Mode=TwoWay}"/>
</TransformGroup>
</Canvas.RenderTransform>
<!-- Bunch of Path objects, omitted for brevity-->
</Canvas>
</Viewbox>
</Window>
相关的代码片段:
namespace TestZaMapu
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TranslationFactorX = 0;
TranslationFactorY = 0;
isPanning = false;
}
// panning variables
private Point ptOldPosition;
private bool isPanning ;
// dependency properties for translation along X and Y axes
public static readonly DependencyProperty TranslateX =
DependencyProperty.Register("TranslationFactorX", typeof(double), typeof(MainWindow));
public static readonly DependencyProperty TranslateY =
DependencyProperty.Register("TranslationFactorY", typeof(double), typeof(MainWindow));
public double TranslationFactorX
{
get { return (double)GetValue(TranslateX); }
set { SetValue(TranslateX, value); }
}
public double TranslationFactorY
{
get { return (double)GetValue(TranslateY); }
set { SetValue(TranslateY, value); }
}
// mouse event handlers for panning
private void GlavniProzor_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
if (isPanning )
return;
isPanning = this.CaptureMouse();
ptOldPosition = e.GetPosition(this);
}
private void GlavniProzor_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
if (this.IsMouseCaptured)
{
this.ReleaseMouseCapture();
isPanning = false;
}
}
private void GlavniProzor_MouseMove(object sender, MouseEventArgs e)
{
base.OnMouseMove(e);
if (isPanning )
{
Point ptNewPosition = e.GetPosition(this);
if (ptNewPosition != ptOldPosition)
{
Vector direction = ptOldPosition - ptNewPosition;
direction.X = TranslationFactorX - direction.X;
direction.Y = TranslationFactorY - direction.Y;
TranslationFactorX = direction.X;
TranslationFactorY = direction.Y;
ptOldPosition = ptNewPosition;
}
}
}
private void GlavniProzor_LostMouseCapture(object sender, MouseEventArgs e)
{
isPanning = false;
this.OnLostMouseCapture(e);
}
}
}
Grid
中,然后再将其包含在ScrollViewer
中。但是由于问题表述过于广泛,无法确定。 - Peter Duniho0.5, 0.5
。然后将Canvas放置在Viewbox内,而该Viewbox是主窗口的内容。我想限制平移,使图像不会移出窗口,留下空白。完整的XAML和代码在帖子底部链接。 - AlwaysLearningNewStuff