在资源有效的情况下使用来自WPF中的Inkscape的矢量图形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在资源有效的情况下使用来自WPF中的Inkscape的矢量图形相关的知识,希望对你有一定的参考价值。

此问题旨在成为如何使用Inkscape创建并保存为XAML的图像的最佳实践。

互联网上有很多文章,但其中很多都没有显示每个解决方案的优缺点。 Example 1Example 2

使用Inkscape创建图像并另存为XAML时,您只能在XAML中使用Viewbox。

<?xml version="1.0" encoding="UTF-8"?>
<!--This file is NOT compatible with Silverlight-->
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
  <Canvas Name="svg8" Width="210" Height="297">
    <Canvas.RenderTransform>
      <TranslateTransform X="0" Y="0"/>
    </Canvas.RenderTransform>
    <Canvas.Resources/>
    <!--Unknown tag: sodipodi:namedview-->
    <!--Unknown tag: metadata-->
    <Canvas Name="layer1">
      <Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Canvas.Left="55.184521" Canvas.Top="113.30357" Width="33.261906" Height="33.261906" Name="rect4485" Fill="#FFFFFFFF" StrokeThickness="5.29166651" Stroke="#FF000000" StrokeMiterLimit="4"/>
    </Canvas>
  </Canvas>
</Viewbox>

要使用此文件,我通常必须将其包装在ResourceDictionary中。这很烦人,因为我不能再在Inkscape中编辑文件而不必删除之前的ResourceDictionary

图像将多次显示,例如在ListViewItem或任何其他具有ItemsSource的元素中。

有没有办法只有一个ResourceDictionary我可以导入所有这些XAML文件?

让我们假设我把它包裹在ResourceDictionary中,并给Viewbox一个x:Key="SquareIcon"值。

显示此元素的最有效资源的方法是什么?

我应该使用ContentPresenter并设置其Content属性并设置Canvas x:Shared="false"

使用Label(或其他一些控件)更有效吗?

也许删除Viewbox并始终在我自己的视图中使用Canvas中的Viewbox

我应该将Viewbox包裹在ControlTemplate中并在ContentPresenter Template财产中使用它吗?这样我就不需要在x:Shared上使用Canvas属性了。

答案

将资产从Inkscape保存为xaml时,可以将其复制到Blend,然后将其转换为Path。然后你有一个该资产的矢量表示,你可以很容易地将其作为style

你可以阅读有关转换到路径here的信息

请记住,您还可以组合多个元素然后进行转换。基本上,任何一种颜色的图像都可以转换为单一路径。

就最佳实践而言,我喜欢将所有与Path / Image / Icon相关的样式保存在单个ResourceDictionary中,然后在App.xaml文件中全局引用它。

另一答案

我认为您可以通过阅读所有文件手动创建它。接下来是步骤:1)您的项目中包含xaml或svg的资源

2)创建你的markup extension,它将通过带有图标的嵌入式资源文件的路径提供Geometry的值。 (它应该解析并提供价值)

3)创建一个自定义控件IconControl,用于显示具有依赖属性IconPath(String)的图标,并通过template binding将其绑定在模板中

  <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="controls:IconControl">
                <Viewbox ><!--Could be other container -->
                     <Path Data="{TemplateBinding IconPath}"
                      Fill="{StaticResource DefaultBrush}" />
                </Viewbox>
            </ControlTemplate>

Viewbox不是很好,因为它将转换应用于内容。因此,您应该使用最简单的容器来获得良好的性能。

4)在标记中使用您的控件

<IconControl IconPath={locl:IconSvgMarkupExtension PathToYourEmbededResourceHere}/>

我在没有VS的情况下从记忆中写出来,所以可能会有一些错误。

我应该将Viewbox包装在ControlTemplate中并在ContentPresenter Template属性中使用它吗?这样我就不需要在Canvas上使用x:Shared属性了。

这也是一种可能的情况,几年前我没有使用相同的方法,因此我的每个图标都是ContentControl,具有不同的模板,取决于Icon。

以上是关于在资源有效的情况下使用来自WPF中的Inkscape的矢量图形的主要内容,如果未能解决你的问题,请参考以下文章

通过 WPF 中的绑定动态设置资源样式

在WPF中的Combobox中绑定

WPF 绑定到资源中的元素

WPF中的多语言[关闭]

防止 WPF 中的内存泄漏

2021-12-11 WPF面试题 什么是静态资源和动态资源?