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

NVM*_*NVM 64 wpf svg

有人可以描述一个推荐的Step by Step程序吗?

编辑:

步骤1.将SVG转换为XAML ......很简单

第2步.怎么办?

Ray*_*rns 130

您的技术将取决于您的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>
Run Code Online (Sandbox Code Playgroud)

使用图像作为图标

图像可以直接使用:

<Button>
  <Image ... />  <!-- Converted from SVG -->
</Button>
Run Code Online (Sandbox Code Playgroud)

使用网格作为图标

网格可以直接使用:

<Button>
  <Grid ... />  <!-- Converted from SVG -->
</Button>
Run Code Online (Sandbox Code Playgroud)

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

<Button>
  <Viewbox ...>
    <Grid ... />  <!-- Converted from SVG -->
  </Viewbox>
</Button>
Run Code Online (Sandbox Code Playgroud)

使用Canvas作为图标

这就像使用图像或网格,但由于画布没有固定的大小,您需要指定高度和宽度(除非这些已由SVG转换器设置):

<Button>
  <Canvas Height="100" Width="100">  <!-- Converted from SVG, with additions -->
  </Canvas>
</Button>
Run Code Online (Sandbox Code Playgroud)

使用路径作为图标

您可以使用路径,但必须明确设置笔划或填充:

<Button>
  <Path Stroke="Red" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>
Run Code Online (Sandbox Code Playgroud)

要么

<Button>
  <Path Fill="Blue" Data="..." /> <!-- Converted from SVG, with additions -->
</Button>
Run Code Online (Sandbox Code Playgroud)

使用几何图形作为图标

您可以使用路径绘制几何体.如果它应该被抚摸,设置描边:

<Button>
  <Path Stroke="Red" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>
Run Code Online (Sandbox Code Playgroud)

或者如果应该填写,请设置填充:

<Button>
  <Path Fill="Blue" Width="100" Height="100">
    <Path.Data>
      <Geometry ... /> <!-- Converted from SVG -->
    </Path.Data>
  </Path>
</Button>
Run Code Online (Sandbox Code Playgroud)

如何绑定数据

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

绑定图纸:

<Button>
  <Rectangle Width="100" Height="100">
    <Rectangle.Fill>
      <DrawingBrush Drawing="{Binding Drawing, Source={StaticResource ...}}" />
    </Rectangle.Fill>
  </Rectangle>
</Button>
Run Code Online (Sandbox Code Playgroud)

绑定图像:

<Button Content="{Binding Image}" />
Run Code Online (Sandbox Code Playgroud)

绑定网格:

<Button Content="{Binding Grid}" />
Run Code Online (Sandbox Code Playgroud)

绑定视图框中的网格:

<Button>
  <Viewbox ...>
    <ContentPresenter Content="{Binding Grid}" />
  </Viewbox>
</Button>
Run Code Online (Sandbox Code Playgroud)

绑定画布:

<Button>
  <ContentPresenter Height="100" Width="100" Content="{Binding Canvas}" />
</Button>
Run Code Online (Sandbox Code Playgroud)

绑定路径:

<Button Content="{Binding Path}" />  <!-- Fill or stroke must be set in code unless set by the SVG converter -->
Run Code Online (Sandbox Code Playgroud)

绑定几何:

<Button>
  <Path Width="100" Height="100" Data="{Binding Geometry}" />
</Button>
Run Code Online (Sandbox Code Playgroud)

  • +10只是花时间举例说明所有情况在我的情况下,我有一个画布,所以我假设以下适用<Button> <Canvas Height ="100"Width ="100"> <! - 从SVG转换,添加 - - > </ Canvas> </ Button>但是我该如何重用呢?我不能复制/粘贴我想要使用svg图像的每个按钮.我有点想将它定义为字典中的资源并用作Static/DynamicResource. (7认同)
  • 您不能在UI中的多个位置使用单个Canvas,因为Visual只能有一个父级.所以你会典型地使用一个模板.模板允许您在每个需要的地方创建Canvas的单独实例:`<ResourceDictionary> <DataTemplate x:Key ="MyIconTemplate"> <Canvas ... /> </ DataTemplate> </ ResourceDictionary>`.. .` <Button> <ContentPresenter ContentTemplate ="{StaticResource MyIconTemplate}"/> </ Button>`. (2认同)

fas*_*ect 41

我找到了在WPF中使用svg图标的最佳方法.我使用sharpvector框架:

Install-Package SharpVectors
Run Code Online (Sandbox Code Playgroud)

所以我的XAML看起来如下:

<UserControl ...
         xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
         ...>
    ...
    <svgc:SvgViewbox Margin="5" Height="20" Width="20" Stretch="Uniform" Source="/View/Resources/Icons/Connection.Closed.Black.svg"/>
    ...
</UserControl>
Run Code Online (Sandbox Code Playgroud)

  • 将XAML Imges嵌入应用程序或使用此方法更好吗? (5认同)

Pol*_*ear 7

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

  1. SharpVectors nuget 包添加到您的项目中。
  2. 将 SVG 文件添加到您的项目中,例如,在“Icons”子文件夹中,并将其Build Action属性设置为Resource
  3. 在您的代码中使用它:
<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>
Run Code Online (Sandbox Code Playgroud)

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

  1. SvgToXaml。下载最新版本(此答案已使用“Ver_1.3.0”进行测试)
  2. 将所有 SVG 图标放入一个文件夹中并执行以下命令:
SvgToXaml.exe BuildDict /inputdir "c:\Icons" /outputdir "c:\MyWpfApp" /outputname IconsDictionary
Run Code Online (Sandbox Code Playgroud)
  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>
Run Code Online (Sandbox Code Playgroud)

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

如果您已经生成了 XAML 文件并且想要使用它们,则可以为其中的某些类型创建自定义 ValueConverter类。更多信息请参考以下回答:


Mah*_*dsi 6

Windows 10 Creators Update(15063)本身支持SVG图像,但有一些问题.

用法就像设置Windows.UI.Xaml.Media.Imaging.SvgImageSource一个Source到SVG的路径一样简单.这相当于使用<Image />,如下:

<Image>
    <Image.Source>
        <SvgImageSource UriSource="Assets/svg/icon.svg" />
    </Image.Source>
</Image>
Run Code Online (Sandbox Code Playgroud)

但是,以这种方式加载的SVG图像(通过XAML)可能会加载锯齿/别名.一种解决方法是指定一个SvgImageSourceRasterizePixelHeight两倍的值+您的实际高度/宽度:

<SvgImageSource RasterizePixelHeight="300" RasterizePixelWidth="300" UriSource="Assets/svg/icon.svg" /> <!-- presuming actual height or width is under 150 -->
Run Code Online (Sandbox Code Playgroud)

这可以通过在基本映像RasterizePixelWidthSvgImageSource事件中创建新动态来动态解决:

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;
Run Code Online (Sandbox Code Playgroud)

在非高dpi屏幕上可能很难看到混叠,但这是尝试说明它.

这是上面代码的结果:ImageOpened使用初始化的一个Image,以及SvgImageSource使用在Image事件中创建的SvgImageSource 的第二个代码:

在此输入图像描述

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

在此输入图像描述

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

在此输入图像描述

(您需要在新标签中打开图像并以全尺寸查看以了解其中的差异)

  • [SvgImageSource](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.imaging.svgimagesource)是一个UWP库,而不是WPF,遗憾的是. (12认同)
  • 这是UWP而不是WPF; 你在混淆XAML (5认同)

Mar*_*cas 5

经过各种搜索和尝试,我设法找到了该方法,而无需使用外部库。首先,您需要使用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"/>
Run Code Online (Sandbox Code Playgroud)
  • 在 XAML 文件中,您必须创建一个ViewBox元素,然后插入一个Grid元素,然后插入Path元素,其次数与在 SVG 文件中看到路径时的次数相同:
<Viewbox Stretch="Fill">
    <Grid>
        <Path Fill="..." Data="..."/>
        <Path Fill="..." Data="..."/>
        <Path Fill="..." Data="..."/>
    </Grid>
</Viewbox>
Run Code Online (Sandbox Code Playgroud)

在 XAML 的属性中,Fill您必须fill在 SVG 文件中插入属性,在DataXAML 的属性中,您必须d在 SVG 文件中插入属性。

你应该得到这样的结果: 在此输入图像描述