应用缩放时滚动 canvas 出现故障(Inkscape 中从 svg 到 xaml 的导出不正确)
Scrolling canvas malfunctions when applying zoom (Incorrect export from svg to xaml in Inkscape)
简介:
我正在尝试通过阅读官方文档和使用 Internet 寻求帮助来自学 WPF。
我有 C++ 和原始 WinAPI 背景,但我确实有一些 C# 和 .NET 的经验,包括 WinForms。
我有 .svg
文件应该显示在主 window 中。应用程序应该提供缩放功能,并且应该能够滚动图像以防图像太大而无法放入主图像 window.
由于WPF无法渲染.svg
,我用Inkscape将文件转换成.xaml
,所以我可以渲染成功。
我为完成任务所做的努力:
由于这里的某些问题,我已经设法解决了滚动部分。缩放也有效,但总体结果并不令人满意。这就是为什么我在这里寻求帮助的原因。在写这个 post 的时候,我正在网上搜索解决方案(虽然仍然没有进展......)。
问题:
放大或缩小时,图片位置不正确,因此滚动条无法完全显示。
由于英语不是我的母语,而且我是WPF的新手,所以我很难解释这个问题。尽管如此,我还是拍了一些快照来证明我在说什么。
让我先从主要 window 的图像开始,当它首次加载到屏幕时:
放大、缩小后出现的问题分别如下:
你可以清楚地看到我无法在第一张图片中向上滚动(放大时)以看到老虎的头顶。
第二张图片我们可以看到老虎错位了,底部水平滚动条看不到,所以我看不到老虎头的底部。
相关信息:
我使用 Inkscape 将 this image 转换为 XAML。 XAML 对于 post 来说太大了(我试过了)所以我展示了我目前所拥有的 XAML 的最低限度:
<Window x:Class="Testing.MainWindow"
Name="myMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" KeyUp="myMainWindow_KeyUp">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<!-- Canvas, and its drawing, were created with Inkscape -->
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="494.44705" Height="510.55356">
<Canvas.RenderTransform>
<TranslateTransform X="183.99798" Y="144.4264"/>
</Canvas.RenderTransform>
<!-- many drawing commands, omitted for brevity -->
</Canvas>
</ScrollViewer>
</Window>
Canvas
元素中的所有内容,包括它的 Height
和 Width
,以及 TranslateTransform
都是由 Inkscape 创建的。这就是为什么我不允许更改该内容。如您所见,我已将 canvas 放置在 scrollviewer 中。
滚动工作正常,但在我应用缩放后它出现故障。
我决定当用户按下 + 时放大,当用户按下 - 时缩小。 KeyUp
事件的处理如下所示。
private void myMainWindow_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Add)
{
Matrix m = svg2.LayoutTransform.Value;
m.M11 += 0.5;
m.M22 += 0.5;
svg2.LayoutTransform = new MatrixTransform(m);
}
if (e.Key == Key.Subtract)
{
Matrix m = svg2.LayoutTransform.Value;
m.M11 -= 0.5;
m.M22 -= 0.5;
svg2.LayoutTransform = new MatrixTransform(m);
}
}
完整的XAML和后面的代码可以找到here。
问题:
我做错了什么?我如何调整提交的代码以便缩放正常工作?
也许使用 ScaleTransform 而不是 MatrixTransform 可能会有所帮助。
所以。 Canvas 是一个轻量级的容器,旨在将元素排列在指定的位置。 Canvas 可以显示其边界外的元素,但如果您在 Canvas 上设置 ClipToBounds="True",那么不出所料,它会裁剪超出其边界的任何内容。
如果你看看你的 xaml:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="494.44705" Height="510.55356">
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform X="183.99798" Y="144.4264"/>
</TransformGroup>
</Canvas.RenderTransform>
你会看到,你的 Canvas 实际上是由 TranslateTransform 移动的。在下图中,您可以看到实际的矩形位置,用红色描边。如果你将设置 ClipToBounds="True" 那么这个矩形之外的所有东西都会被剪掉。 (我建议你检查一下名为 Snoop 的程序,它非常有用)
当我发现你的 canvas 有变形时,我决定重新生成你有的图像。
有两种常见的方法:手动(打印为 XPS 文档并提取相关 xaml)或 Inkscape。
我试过第一种方法,但失败了。所以,我使用了最新版本的 Inkscape。
我关注的是以下方框:
然后我将 svg 保存为 xaml 并选中 "Compatible with Silverlight" 选项。
结果如下:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="900" Height="900">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas Name="g4">
<!-- data below -->
并且一切正常没有故障。这是 xaml 我有 http://pastebin.com/tRin96Hi
所以这都是关于不适合 canvas 矩形的线条。
更新
逐步说明如何在 Inkscape 中将 x 和 y 设置为 0。
- 已下载最新版本的 Inkscape (0.91)
- 已安装
- 已下载 svg 图片
- 用"Open with... -> Inkscape"
打开
- Ctrl + A 到select所有数字
- 第 5 步启用 x 和 y 框。在框中打印 0 并按 Enter(或切换到其他框)以应用更改。对 x 和 y 框都应用 0。
- (可选)文件-文档属性-页面-高度&宽度,如果需要裁剪
- 已将 svg 另存为 xaml,并选中 "Compatible with Silverlight" 选项。
简介:
我正在尝试通过阅读官方文档和使用 Internet 寻求帮助来自学 WPF。
我有 C++ 和原始 WinAPI 背景,但我确实有一些 C# 和 .NET 的经验,包括 WinForms。
我有 .svg
文件应该显示在主 window 中。应用程序应该提供缩放功能,并且应该能够滚动图像以防图像太大而无法放入主图像 window.
由于WPF无法渲染.svg
,我用Inkscape将文件转换成.xaml
,所以我可以渲染成功。
我为完成任务所做的努力:
由于这里的某些问题,我已经设法解决了滚动部分。缩放也有效,但总体结果并不令人满意。这就是为什么我在这里寻求帮助的原因。在写这个 post 的时候,我正在网上搜索解决方案(虽然仍然没有进展......)。
问题:
放大或缩小时,图片位置不正确,因此滚动条无法完全显示。
由于英语不是我的母语,而且我是WPF的新手,所以我很难解释这个问题。尽管如此,我还是拍了一些快照来证明我在说什么。
让我先从主要 window 的图像开始,当它首次加载到屏幕时:
放大、缩小后出现的问题分别如下:
你可以清楚地看到我无法在第一张图片中向上滚动(放大时)以看到老虎的头顶。
第二张图片我们可以看到老虎错位了,底部水平滚动条看不到,所以我看不到老虎头的底部。
相关信息:
我使用 Inkscape 将 this image 转换为 XAML。 XAML 对于 post 来说太大了(我试过了)所以我展示了我目前所拥有的 XAML 的最低限度:
<Window x:Class="Testing.MainWindow"
Name="myMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" KeyUp="myMainWindow_KeyUp">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<!-- Canvas, and its drawing, were created with Inkscape -->
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="494.44705" Height="510.55356">
<Canvas.RenderTransform>
<TranslateTransform X="183.99798" Y="144.4264"/>
</Canvas.RenderTransform>
<!-- many drawing commands, omitted for brevity -->
</Canvas>
</ScrollViewer>
</Window>
Canvas
元素中的所有内容,包括它的 Height
和 Width
,以及 TranslateTransform
都是由 Inkscape 创建的。这就是为什么我不允许更改该内容。如您所见,我已将 canvas 放置在 scrollviewer 中。
滚动工作正常,但在我应用缩放后它出现故障。
我决定当用户按下 + 时放大,当用户按下 - 时缩小。 KeyUp
事件的处理如下所示。
private void myMainWindow_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Add)
{
Matrix m = svg2.LayoutTransform.Value;
m.M11 += 0.5;
m.M22 += 0.5;
svg2.LayoutTransform = new MatrixTransform(m);
}
if (e.Key == Key.Subtract)
{
Matrix m = svg2.LayoutTransform.Value;
m.M11 -= 0.5;
m.M22 -= 0.5;
svg2.LayoutTransform = new MatrixTransform(m);
}
}
完整的XAML和后面的代码可以找到here。
问题:
我做错了什么?我如何调整提交的代码以便缩放正常工作?
也许使用 ScaleTransform 而不是 MatrixTransform 可能会有所帮助。
所以。 Canvas 是一个轻量级的容器,旨在将元素排列在指定的位置。 Canvas 可以显示其边界外的元素,但如果您在 Canvas 上设置 ClipToBounds="True",那么不出所料,它会裁剪超出其边界的任何内容。
如果你看看你的 xaml:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="494.44705" Height="510.55356">
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform X="183.99798" Y="144.4264"/>
</TransformGroup>
</Canvas.RenderTransform>
你会看到,你的 Canvas 实际上是由 TranslateTransform 移动的。在下图中,您可以看到实际的矩形位置,用红色描边。如果你将设置 ClipToBounds="True" 那么这个矩形之外的所有东西都会被剪掉。 (我建议你检查一下名为 Snoop 的程序,它非常有用)
当我发现你的 canvas 有变形时,我决定重新生成你有的图像。 有两种常见的方法:手动(打印为 XPS 文档并提取相关 xaml)或 Inkscape。 我试过第一种方法,但失败了。所以,我使用了最新版本的 Inkscape。 我关注的是以下方框:
然后我将 svg 保存为 xaml 并选中 "Compatible with Silverlight" 选项。 结果如下:
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Name="svg2" Width="900" Height="900">
<Canvas.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Canvas.RenderTransform>
<Canvas Name="g4">
<!-- data below -->
并且一切正常没有故障。这是 xaml 我有 http://pastebin.com/tRin96Hi 所以这都是关于不适合 canvas 矩形的线条。
更新 逐步说明如何在 Inkscape 中将 x 和 y 设置为 0。
- 已下载最新版本的 Inkscape (0.91)
- 已安装
- 已下载 svg 图片
- 用"Open with... -> Inkscape" 打开
- Ctrl + A 到select所有数字
- 第 5 步启用 x 和 y 框。在框中打印 0 并按 Enter(或切换到其他框)以应用更改。对 x 和 y 框都应用 0。
- (可选)文件-文档属性-页面-高度&宽度,如果需要裁剪
- 已将 svg 另存为 xaml,并选中 "Compatible with Silverlight" 选项。