在WPF中使用SVG文件作为图标的正确方法是什么

qqrboqgw  于 2022-11-18  发布在  其他
关注(0)|答案(9)|浏览(131)

有人能描述一下推荐的逐步执行程序吗?
步骤1.将SVG转换为XAML...很简单
第二步。现在怎么办?

ykejflvf

ykejflvf1#

您的技术将取决于SVG到XAML转换器生成的XAML对象。它生成的是绘图?图像?网格?画布?路径?几何图形?在每种情况下,您的技术将有所不同。
在下面的示例中,我将假设您在按钮上使用图标,这是最常见的情况,但请注意,相同的技术将适用于任何ContentControl。

使用绘图作为图标

要使用绘图,请使用DrawingBrush绘制一个大小合适的矩形:

<Button>
  <Rectangle Width="100" Height="100">
    <Rectangle.Fill>
      <DrawingBrush>
        <DrawingBrush.Drawing>

          <Drawing ... /> <!-- Converted from SVG -->

        </DrawingBrush.Drawing>
      </DrawingBrush>
    </Rectangle.Fill>
  </Rectangle>
</Button>

使用图像作为图标

可以直接使用图像:

<Button>
  <Image ... />  <!-- Converted from SVG -->
</Button>

将网格用作图标

网格可以直接用于:

<Button>
  <Grid ... />  <!-- Converted from SVG -->
</Button>

如果需要控制大小,也可以将其包含在Viewbox中:

<Button>
  <Viewbox ...>
    <Grid ... />  <!-- Converted from SVG -->
  </Viewbox>
</Button>

将画布用作图标

这类似于使用图像或网格,但由于画布没有固定大小,因此需要指定高度与宽度(除非SVG转换器已设置了高度与宽度):

<Button>
  <Canvas Height="100" Width="100">  <!-- Converted from SVG, with additions -->
  </Canvas>
</Button>

使用路径作为图标

您可以使用Path,但必须明确设定笔画或填色:

<Button>
  <Path Stroke="Red" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>

<Button>
  <Path Fill="Blue" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>

将几何图形用作图标

您可以使用路径来绘制您的几何图形。如果需要绘制,请设定笔画:

<Button>
  <Path Stroke="Red" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>

或者如果应该填充,请将“填充:

<Button>
  <Path Fill="Blue" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>

如何进行数据绑定

如果您在代码中执行SVG -〉XAML转换,并希望使用数据绑定显示生成的XAML,请使用以下方法之一:
绑定绘图:

<Button>
  <Rectangle Width="100" Height="100">
    <Rectangle.Fill>
      <DrawingBrush Drawing="{Binding Drawing, Source={StaticResource ...}}" />
    </Rectangle.Fill>
  </Rectangle>
</Button>

绑定图像:

<Button Content="{Binding Image}" />

绑定网格:

<Button Content="{Binding Grid}" />

在Viewbox中绑定网格:

<Button>
  <Viewbox ...>
    <ContentPresenter Content="{Binding Grid}" />
  </Viewbox>
</Button>

绑定画布:

<Button>
  <ContentPresenter Height="100" Width="100" Content="{Binding Canvas}" />
</Button>

绑定路径:

<Button Content="{Binding Path}" />  <!-- Fill or stroke must be set in code unless set by the SVG converter -->

绑定几何图形:

<Button>
  <Path Width="100" Height="100" Data="{Binding Geometry}" />
</Button>
brgchamk

brgchamk2#

安装SharpVectors程式库

Install-Package SharpVectors

在XAML中添加以下内容

<UserControl xmlns:svgc="http://sharpvectors.codeplex.com/svgc">
    <svgc:SvgViewbox Source="/Icons/icon.svg"/>
</UserControl>
0ve6wy6x

0ve6wy6x3#

Windows 10内部版本15063“创建者更新”原生支持SVG图像(尽管有一些陷阱)到面向Windows 10的UWP/UAP应用程序。

  • 如果您的应用程序是WPF应用程序而不是UWP/UAP,您仍然可以使用此API(在经历了相当多的限制之后):Windows 10 build 17763“2018年10月更新”引入了XAML岛的概念(作为“预览”技术但我相信在应用商店中允许;在所有情况下,随着Windows 10内部版本18362“2019年5月更新”,XAML岛不再是预览功能,并且完全受支持),允许您在WPF应用程序中使用UWP API和控件。*
  • 您需要首先添加对WinRT API的引用,并使用某些与用户数据或系统交互的Windows 10 API(例如,在Windows 10 UWP Web视图中从磁盘加载图像或使用吐司通知API显示Toast),您还需要将WPF应用程序与软件包标识相关联,如此处所示(在Visual Studio 2019中非常简单)。不过,使用Windows.UI.Xaml.Media.Imaging.SvgImageSource类时不一定需要这样做。*

用法(如果您使用的是UWP,或者您已经按照上面的说明在WPF下添加了XAML岛支持)非常简单,只需将<Image />Source设置为SVG的路径即可。这相当于使用SvgImageSource,如下所示:

<Image>
    <Image.Source>
        <SvgImageSource UriSource="Assets/svg/icon.svg" />
    </Image.Source>
</Image>

但是,以这种方式(通过XAML)加载的SVG图像可能会加载锯齿状/锯齿状图像。一种解决方法是指定RasterizePixelHeightRasterizePixelWidth值,该值是实际高度/宽度的两倍:

<SvgImageSource RasterizePixelHeight="300" RasterizePixelWidth="300" UriSource="Assets/svg/icon.svg" /> <!-- presuming actual height or width is under 150 -->

通过在基本映像的ImageOpened事件中创建一个新的SvgImageSource,可以动态解决此问题:

var svgSource = new SvgImageSource(new Uri("ms-appx://" + Icon));
PrayerIcon.ImageOpened += (s, e) =>
{
    var newSource = new SvgImageSource(svgSource.UriSource);
    newSource.RasterizePixelHeight = PrayerIcon.DesiredSize.Height * 2;
    newSource.RasterizePixelWidth = PrayerIcon.DesiredSize.Width * 2;
    PrayerIcon2.Source = newSource;
};
PrayerIcon.Source = svgSource;

在非高dpi屏幕上可能很难看到锯齿,但这里试图说明它。
这是上面代码的结果:一个使用初始SvgImageSourceImage,以及它下面的第二个使用ImageOpened事件中创建的SvgImageSource的Image

这是顶部图像的放大视图:

而这是底部(抗锯齿,正确)图像的放大视图:

(you需要在新标签页中打开图像并以全尺寸查看以欣赏差异)

hmtdttj4

hmtdttj44#

经过各种搜索和尝试,我设法找到了方法,而不必使用外部库。首先,您将需要使用Inkscape打开SVG文件进行准备,然后按照以下列表中的步骤操作:

  • 用Inkscape打开SVG文件;
  • 按Ctrl + A选择所有内容;
  • 转到“编辑”〉“根据所选内容调整页面大小”;
  • 按Ctrl + C组合键;
  • 按下Ctrl + S,然后关闭Inkscape;
  • 在文件编辑器中打开SVG文件,然后转到<path>,您可以查看多个路径。以下是一个示例:
<path d="..." fill="..." id="path2"/>
<path d="..." fill="..." id="path4"/>
<path d="..." fill="..." id="path6"/>
  • 在您的XAML文件中,您必须创建一个ViewBox元素,然后插入一个Grid元素,然后插入Path元素,次数为在SVG文件中看到路径时的次数:
<Viewbox Stretch="Fill">
    <Grid>
        <Path Fill="..." Data="..."/>
        <Path Fill="..." Data="..."/>
        <Path Fill="..." Data="..."/>
    </Grid>
</Viewbox>

在XAML的Fill属性中,您必须在SVG档案中插入fill属性,而在XAML的Data属性中,您必须在SVG档案中插入d属性。
您应该会得到这样的结果:

3pmvbmvn

3pmvbmvn5#

选项1:使用“SharpVectors”nuget包直接使用SVG图标

1.将SharpVectors nuget包添加到项目中。
1.将SVG文件添加到项目中(例如,“Icons”子文件夹中),并将其Build Action属性设置为Resource
1.在代码中使用它:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <Button Height="100">
                <svgc:SvgViewbox Source="/Icons/Checkmark_16x.svg"/>
            </Button>
            <ContentControl Height="100">
                <svgc:SvgViewbox Source="/Icons/CollapseAll_16x.svg"/>
            </ContentControl>
            <Label Height="100">
                <svgc:SvgViewbox Source="/Icons/Refresh_16x.svg"/>
            </Label>
        </StackPanel>
    </Grid>
</Window>

选项2:使用“SvgToXaml”工具将SVG转换为XAML

  1. SvgToXaml。下载latest release(此答案已使用“Ver_1.3.0”进行了测试)
    1.将所有SVG图标放置到一个文件夹中,然后执行以下命令:
SvgToXaml.exe BuildDict /inputdir "c:\Icons" /outputdir "c:\MyWpfApp" /outputname IconsDictionary

1.将生成的IconsDictionary.xaml文件添加到项目中,并在代码中使用它:

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="IconsDictionary.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button Height="100">
                <Image Source="{StaticResource Refresh_16xDrawingImage}"/>
            </Button>
            <ContentControl Height="100">
                <Image Source="{StaticResource CollapseAll_16xDrawingImage}"/>
            </ContentControl>
            <Label Height="100">
                <Image Source="{StaticResource Checkmark_16xDrawingImage}"/>
            </Label>
        </StackPanel>
    </Grid>
</Window>

选项3:对某些已生成的XAML文件使用IValueConverter

如果您已经产生XAML档案,而且想要使用这些档案,则可以针对某些类型的档案建立自订ValueConverter类别。如需详细信息,请参阅下列答案:

h7wcgrx3

h7wcgrx36#

您可以使用SVG生成的xaml作为矩形的画笔。

<Rectangle>
   <Rectangle.Fill>
      --- insert the converted xaml's geometry here ---
   </Rectangle.Fill>
</Rectangle>
c8ib6hqw

c8ib6hqw7#

使用SvgImage或SvgImageConverter扩展,SvgImageConverter支持绑定。请参阅以下链接以获取演示这两种扩展的示例。
https://github.com/ElinamLLC/SharpVectors/tree/master/TutorialSamples/ControlSamplesWpf

ui7jx7zq

ui7jx7zq8#

我们可以直接使用SVG代码中的路径代码:

<Path>
        <Path.Data>
            <PathGeometry Figures="M52.8,105l-1.9,4.1c ...
lmvvr0a8

lmvvr0a89#

另一种方法是dotnetprojects SVGImage
这允许直接在xaml中原生使用.svg文件。
好的部分是,它只是一个程序集,大约是100K。与SharpVectors相比,它比任何文件都大得多。
用法:

...
xmlns:svg1="clr-namespace:SVGImage.SVG;assembly=DotNetProjects.SVGImage"
...
<svg1:SVGImage Name="mySVGImage" Source="/MyDemoApp;component/Resources/MyImage.svg"/>
...

就这样了
请参阅:

相关问题