使用SVG/Path
WPF支持绘图,在WPF中定义了一些基本图形,如Line、Rectangle、Ellipse、Path等
其中Path支持使用路径来进行绘图,所以大部分的图标可以通过Path来进行绘制。
因为本文主要是介绍矢量图标,所以不对绘图进行详细介绍,只介绍一些核心概念
Path的路径标记语法
这里涉及了其它各种图形,所以需要对WPF中的图形有一定的了解,可以参考后面的链接。
下面我们绘制一个简单的图形
1、打开Expression Blend,创建一个WPF工程,使用钢笔绘制一个简单的图标
说明:这里仅作演示,是随便绘的,可以根据实际需求进行绘制,如果不了解Blend的使用,可以参考后面的链接。
2、在界面上绘制后,生成的XAML代码如下:
1 <Path Data="M369.20455,99.305455 C480.96663,70.225598 475.06774,124.37409 332.90865,172.44228 190.74956,220.51046 431.91422,217.02243 431.91422,217.02243 431.91422,217.02243 257.44246,128.38531 369.20455,99.305455 z" Fill="#FFF4F4F5" Height="127" Canvas.Left="288.424" Stroke="Black" Stretch="Fill" Canvas.Top="91.11" Width="159"/> 2 <Path Data="M512.38636,181.12364" Fill="#FFF4F4F5" Height="1" Canvas.Left="512.386" Stroke="Black" Stretch="Fill" Canvas.Top="181.124" Width="1"/>
3、将路径合并
此时的Path如下:
1 <Path Data="M81.202054,8.6827316 C192.34125,-20.408055 186.47523,33.760794 45.10845,81.847042 -96.258336,129.93329 143.56222,126.44395 143.56222,126.44395 143.56222,126.44395 -29.937139,37.773518 81.202054,8.6827316 z M224.46202,90.513998" Fill="#FFF4F4F5" Height="127" Canvas.Left="288.424" Stroke="Black" Stretch="Fill" Canvas.Top="91.11" Width="225" HorizontalAlignment="Center" VerticalAlignment="Center"/>
4、将绘制的图形应用到按钮中
在https://www.cnblogs.com/zhaotianff/p/9844457.html这篇文章中,我封装了一个按钮控件,这里我们直接拿来用
1 <Window.Resources> 2 <Canvas x:Key="Icon.Test" Width="196" Height="127"> 3 <Path Data="M81.202054,8.6827316 C192.34125,-20.408055 186.47523,33.760794 45.10845,81.847042 -96.258336,129.93329 143.56222,126.44395 143.56222,126.44395 143.56222,126.44395 -29.937139,37.773518 81.202054,8.6827316 z M224.46202,90.513998" Fill="#FFF4F4F5" Stroke="Black" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center"/> 4 </Canvas> 5 </Window.Resources> 6 <Grid> 7 <controls:ImageButton Width="108" Height="112" Content="{StaticResource Icon.Test}" Text="Hello"/> 8 </Grid>
运行效果如下:
调整一下按钮大小:
1 <Window.Resources> 2 <Canvas x:Key="Icon.Test" Width="196" Height="127"> 3 <Path Data="M81.202054,8.6827316 C192.34125,-20.408055 186.47523,33.760794 45.10845,81.847042 -96.258336,129.93329 143.56222,126.44395 143.56222,126.44395 143.56222,126.44395 -29.937139,37.773518 81.202054,8.6827316 z M224.46202,90.513998" Fill="#FFF4F4F5" Stroke="Black" Stretch="Fill" HorizontalAlignment="Center" VerticalAlignment="Center"/> 4 </Canvas> 5 </Window.Resources> 6 <Grid> 7 <controls:ImageButton Width="308" Height="270" Content="{StaticResource Icon.Test}" Text="Hello"/> 8 </Grid>
运行效果:
可以看到图标并不会失真。
但是如果每一个图标我们都自己进行绘制的话,太麻烦,就可以使用SVG,目前网上很多图标网站都可以下载图标的SVG版本。
SVG:可缩放矢量图形(Scalable Vector Graphics,SVG)基于 XML 标记语言,用于描述二维的矢量图形。
SVG中采用的路径语法和WPF中是一致的,所以我们可以直接拿来用。
如何在WPF中使用SVG图标
这里我们以阿里巴巴矢量图标库为例。
1、打开iconfont-阿里巴巴矢量图标库,搜索自己想要的图标
我这里搜索一个star,然后下载svg版本
2、用记事本打开如下
3、我们手动转换一下(将属性小写改为大写、d改为data、p-id等非WPF属性直接删除),得到如下XAML
1 <Path Data="M908.1 353.1l-253.9-36.9L540.7 86.1c-3.1-6.3-8.2-11.4-14.5-14.5-15.8-7.8-35-1.3-42.9 14.5L369.8 316.2l-253.9 36.9c-7 1-13.4 4.3-18.3 9.3-12.3 12.7-12.1 32.9 0.6 45.3l183.7 179.1-43.4 252.9c-1.2 6.9-0.1 14.1 3.2 20.3 8.2 15.6 27.6 21.7 43.2 13.4L512 754l227.1 119.4c6.2 3.3 13.4 4.4 20.3 3.2 17.4-3 29.1-19.5 26.1-36.9l-43.4-252.9 183.7-179.1c5-4.9 8.3-11.3 9.3-18.3 2.7-17.5-9.5-33.7-27-36.3zM664.8 561.6l36.1 210.3L512 672.7 323.1 772l36.1-210.3-152.8-149L417.6 382 512 190.7 606.4 382l211.2 30.7-152.8 148.9z" Fill="LightPink"></Path>
可以看到这里的起点是M908.1 353.11,坐标数很大了,所以直接使用这个图标的话,肯定会显示在理想区域之外。
这里提供两个方法,
一、使用ViewBox进行缩放,可以看到在SVG中也是使用了viewBox进行缩放的。
将ViewBox的宽高定义成实际需求的宽高即可,但是要注意的是,要保持图标的原始比例。
1 <Viewbox Stretch="Uniform" StretchDirection="Both" Width="128" Height="128"> 2 <Path Data="M908.1 353.1 ........ 152.8 148.9z" Fill="LightPink"></Path> 3 </Viewbox>
二、使用工具进行裁剪
以前微软是有个工具叫Microsoft Expression Blend,功能很强大,可以自己绘制,也可以将svg转路径,png转路径,但是现在找不到下载地址了。
这里以Inkscape为例了
可以到官网下载Inkscape安装包:Inkscape 1.3.2 - Windows | Inkscape
觉得下载太慢,可以到这里下载:https://download.csdn.net/download/zhaotianff/88927104 (0积分)
下载完成后,我们用Inkscape打开svg,先选中图形, 按住shift,然后拖动角标,将图标进行缩放
然后在编辑菜单中选择页面设置为选区大小
打开文件菜单,选择另存为,选择微软XAML
按下图设置就可以了
导出结果如下,我们可以直接复制Canvas到WPF中使用
实际运行效果如下:
说明:这里仅提供一个思路,因为矢量图的设计我也不熟悉,Inkscape我也是第一次用。
实际想达到最佳效果,还需要自行尝试。
使用IconFont
什么是IconFont
IconFont是包含符号和字形而不是字母或数字的字体。 它们在网络设计人员中很受欢迎,因为可以用CSS与常规文本相同的方式设置样式。另外,它也是矢量的。
最初IconFont是在Web开发中广泛使用的,但是也可以放到WPF中进行使用。
这里用得多的就是Font Awesome,官网地址:Font Awesome
在WPF中使用Font Awesome的方法
1、我们打开下载地址,选择桌面免费版
下载完成后,解压
2、新建一个WPF工程,增加一个Fonts文件夹
复制"\fontawesome-free-6.5.1-desktop\otfs\Font Awesome 6 Free-Solid-900.otf"到工程Fonts文件夹中,并将文件生成操作改为Resource
3、定义一个字体样式
1 <FontFamily x:Key="FontawesomeStyle">/Fonts/#Font Awesome 6 Free Solid</FontFamily>
4、然后到官网搜索自己想要的图标,如star,复制图标的Unicode
5、还是使用前面定义的ImageButton控件,使用Icon Font时,将文本设置为 &#fxxxx; 即可,xxxx为Unicode代码
1 <controls:ImageButton Grid.Column="1" Width="256" Height="270" Content="" FontFamily="{StaticResource FontawesomeStyle}" Text="Hello World"/>
运行效果:
使用开源的矢量图标库
这里以MahApps.Metro.IconPacks为例
项目地址:NuGet Gallery | MahApps.Metro.IconPacks 5.0.0
这是一套免费的图标库,原理跟第一种方式是一样的,但是可以直接拿来用,很方便。
使用步骤
1、下载图标浏览器, 方便查找图标
Release IconPacks.Browser v1.0.0 · MahApps/IconPacks.Browser · GitHub
2、搜索自己想要的图标,如star,然后复制代码
3、创建一个WPF工程,添加命名空间前缀
1 xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
4、增加一个按钮,还是以前面的ImageButton为例,按钮的内容设置为图标内容,如下:
1 <controls:ImageButton Grid.Row="1" Width="256" Height="270" Text="Hello World"> 2 <controls:ImageButton.Content> 3 <iconPacks:PackIconUnicons Kind="Favorite" /> 4 </controls:ImageButton.Content> 5 </controls:ImageButton>
运行效果如下:
示例代码
参考资料
路径标记语法
路径标记语法 - WPF .NET Framework | Microsoft Learn
WPF绘图概述
Graphics rendering overview - WPF .NET Framework | Microsoft Learn
Blend For Visual Studio概述
Blend for Visual Studio 功能导览 | Microsoft Learn