有人能描述一下做这件事的推荐逐步程序吗?
步骤1:将SVG转换为XAML...那很容易
步骤2:现在该怎么做呢?
你的技术取决于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>
如何将几何图形用作图标
您可以使用路径(Path)绘制您的几何图形。如果需要描边,请设置 Stroke 属性:
<Button>
<Path Stroke="Red" Width="100" Height="100">
<Path.Data>
<Geometry ... /> <!-- Converted from SVG -->
</Path.Data>
</Path>
</Button>
或者如果它应该被填充,设置 Fill:
<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>
<ResourceDictionary><DataTemplate x:Key="MyIconTemplate"><Canvas ... /></DataTemplate></ResourceDictionary>
... <Button><ContentPresenter ContentTemplate="{StaticResource MyIconTemplate}" /></Button>
. - Ray Burns<ResourceDictionary><VisualBrush x:Key="MyBrush"><VisualBrush.Visual><Canvas x:Key="MyCanvas" ... /></VisualBrush.Visual></VisualBrush></ResourceDictionary>
... <Button><Rectangle Fill="{StaticResource MyBrush}" Width="..." Height="..." /></Button>
。这种方法更难,因为您还必须确保Canvas被测量/排列,并且必须硬编码Width/Height(或者为矩形使用模板)。 - Ray BurnsCanvas
对象,我应该把SVG放在哪里?这很重要,因为我的SVG都在静态资源中,我需要将它们嵌入... - code4lifeInstall-Package SharpVectors
<UserControl xmlns:svgc="http://sharpvectors.codeplex.com/svgc">
<svgc:SvgViewbox Source="/Icons/icon.svg"/>
</UserControl>
Windows 10 build 15063 "Creators Update"原生支持SVG图像(尽管存在一些注意事项),可用于针对Windows 10的UWP/UAP应用程序。
如果您的应用程序是WPF应用程序而不是UWP/UAP,则仍然可以使用此API(需要跳过很多障碍):Windows 10 build 17763“2018年10月更新”引入了XAML岛的概念(作为“预览”技术,但我相信允许在应用商店中使用;在所有情况下,随着Windows 10 build 18362“2019年5月更新”,XAML岛不再是预览功能并得到完全支持),允许您在WPF应用程序中使用UWP API和控件。
你需要首先添加对WinRT API的引用。如果要使用与用户数据或系统交互的某些Windows 10 API(例如,在Windows 10 UWP webview中从磁盘加载图像或使用toast通知API显示toast),您还需要将WPF应用程序与包标识相关联,如此处所示(在Visual Studio 2019中更加简便)。虽然这不是使用Windows.UI.Xaml.Media.Imaging.SvgImageSource
类所必需的。<Image />
的Source
设置为SVG路径即可。这相当于使用SvgImageSource
,如下所示:<Image>
<Image.Source>
<SvgImageSource UriSource="Assets/svg/icon.svg" />
</Image.Source>
</Image>
RasterizePixelHeight
或RasterizePixelWidth
值,其值为您实际高度/宽度的两倍以上:<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屏幕可能难以看到。
这是上面代码的结果:一个使用初始SvgImageSource
的Image
,以及下面的第二个Image
,它使用在ImageOpened
事件中创建的SvgImageSource:
这是顶部图像的放大视图:
这是底部图像的放大视图(抗锯齿,正确):你需要在新标签页中打开图片并查看全尺寸才能体会差异。
生成操作
属性为资源
<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>
SvgToXaml.exe BuildDict /inputdir "c:\Icons" /outputdir "c:\MyWpfApp" /outputname IconsDictionary
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>
如果你已经有了一些生成的XAML文件并想要使用它们,在某些类型的文件中可以创建自定义ValueConverter
类。请参考以下答案获取更多信息:
经过多次搜索和尝试,我成功找到了不需要使用外部库的方法。首先,您需要使用Inkscape打开SVG文件进行准备,然后按照以下列表中的步骤进行操作:
<path>
,您可以查看到多个路径。这是一个示例:<path d="..." fill="..." id="path2"/>
<path d="..." fill="..." id="path4"/>
<path d="..." fill="..." id="path6"/>
ViewBox
元素,然后插入一个Grid
元素,然后为SVG文件中看到的路径次数插入Path
元素。<Viewbox Stretch="Fill">
<Grid>
<Path Fill="..." Data="..."/>
<Path Fill="..." Data="..."/>
<Path Fill="..." Data="..."/>
</Grid>
</Viewbox>
Fill
属性中,您需要插入SVG文件中的fill
属性,在您的XAML中的Data
属性中,您需要插入SVG文件中的d
属性。您应该得到这样的结果:
<Rectangle>
<Rectangle.Fill>
--- insert the converted xaml's geometry here ---
</Rectangle.Fill>
</Rectangle>
https://github.com/ElinamLLC/SharpVectors/tree/master/TutorialSamples/ControlSamplesWpf
另一个选择是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"/>
...
就是这样。
请看:
我们可以直接从SVG代码中使用路径代码:
<Path>
<Path.Data>
<PathGeometry Figures="M52.8,105l-1.9,4.1c ...
path
更改为 Path
,将 d
更改为 Data
。可能有很多不同的元素我不知道如何移植,但一个简单的标志可以像这样使用。 - Boppity Bop我发现这个教程非常有帮助: https://msadowski.github.io/WPF-vector-graphics-tutorial/
该教程通过示例详细解释了所有步骤。我已经尝试过了,我的svg图像现在在我的应用程序中显示得很好。