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

问题描述 投票:61回答:4

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

编辑:

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

第2步。怎么办?

wpf svg
4个回答
121
投票

您的技术将取决于您的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>

使用Canvas作为图标

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

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

使用路径作为图标

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

<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}" />

绑定视图框中的网格:

<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>

40
投票

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

Install-Package SharpVectors

所以我的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>

5
投票

Windows 10 build 15063“Creators Update”本身支持针对Windows 10的UWP / UAP应用程序的SVG图像(虽然有一些问题)。

如果您的应用程序是WPF应用程序而不是UWP / UAP,您仍然可以使用此API(在经历了相当多的箍之后):Windows 10 build 17763“2018年10月更新”引入了XAML岛的概念(作为“预览“技术,但我认为允许在应用程序商店;在所有情况下,使用Windows 10 build 18362”2019年5月更新“XAML孤岛不再是预览功能并且完全支持”,允许您在WPF中使用UWP API和控件应用。

您需要首先使用add the references to the WinRT APIs,并使用某些与用户数据或系统交互的Windows 10 API(例如,在Windows 10 UWP webview中从磁盘加载图像或使用toast通知API显示toast),您还需要关联带有包标识的WPF应用程序,as shown here(在Visual Studio 2019中非常容易)。但是,这不应该是使用Windows.UI.Xaml.Media.Imaging.SvgImageSource类所必需的。

用法(如果您使用的是UWP,或者您已按照上述说明并在WPF下添加了XAML岛支持)就像将Source<Image />设置为SVG的路径一样简单。这相当于使用SvgImageSource,如下所示:

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

但是,SVG图像以这种方式加载(通过XAML)may load jagged/aliased。一种解决方法是指定RasterizePixelHeightRasterizePixelWidth值为double +实际高度/宽度:

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

这可以通过在SvgImageSource事件中为基本图像创建新的ImageOpened来动态解决:

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屏幕上可能很难看到混叠,但这是尝试说明它。

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

enter image description here

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

enter image description here

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

enter image description here

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


3
投票

您可以将SVG中生成的xaml用作矩形上的绘图画笔。像这样的东西:

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

0
投票

使用SvgImage或SvgImageConverter扩展,SvgImageConverter支持绑定。有关展示这两种扩展的示例,请参阅以下链接。

https://github.com/ElinamLLC/SharpVectors/tree/master/TutorialSamples/ControlSamplesWpf

© www.soinside.com 2019 - 2024. All rights reserved.