WPF开发随笔收录-自定义图标控件
一、前言
1、在以前自学的过程中,软件需要使用到图标的时候,总是第一个想法是下载一个图片来充当图标使用,但实际得出来的效果会出现模糊的现象。后来网上学习了字体图标库的用法,可以在阿里云矢量图网站那里将想要的图标添加到项目中,然后打包下载得到ttf图标库,然后将图标当成字体来引用即可,这种方法实现的图标是矢量图,放大缩小都不会影响图标的清晰度。
2、但在使用过程中,如果还想要添加一些新的图标时,就得重新下载字体库文件替换,感觉有点麻烦。在同事那里学到了另一种方法,通过下载svg图标,然后修改为xaml的path来实现,话不多说,直接介绍实现方法。
二、正文
1、首先新建一个工程,工程的目录如下图,Controls下的就是自定义的一个图标控件,Enums下的是用来存放图标名称的枚举变量,Resources下的Icons是用来存放xaml图标的。
2、网页登陆阿里巴巴矢量图标库,挑选出自己想要的图标,然后下载对应的svg格式,如下图
3、下载完成后选择以文本的形式打开,然后找到里面的path,如下图。将这部分的路径值复制出来,然后将工程目录的Icons下新建一个home.xaml的文件,将路径粘贴进去,修改一下就得到我们想要的文件。
home.xaml的代码如下,因为XamlIcon这个控件是继承Label的,所以图标的填充色这里绑定到了Foreground这个属性。还有一个点就是,记得选中home.xaml文件,打开属性页面,将生成操作改为资源。
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid Width="1025" Height="1024"> <Path Data="M867.2672 561.792c-81.216-66.496-162.048-133.376-243.072-200.128C586.9472 331.008 549.6992 300.352 512.3872 269.568c-3.264 2.368-6.016 4.288-8.64 6.4C387.2032 372.096 270.5312 468.16 154.2432 564.608 149.9552 568.192 146.9472 575.936 146.8832 581.76c-0.448 97.344-0.384 194.752-0.256 292.096 0 30.208 15.936 45.824 46.464 45.824 74.944 0.064 149.824 0 224.768 0 4.032 0 8.064-0.448 13.184-0.768 0-81.344 0-161.6 0-242.432 54.336 0 107.52 0 161.856 0 0 80.576 0 160.896 0 243.264 6.144 0 10.24 0 14.4 0 74.112 0 148.16 0 222.272 0 32.768 0 47.936-15.232 47.936-48.32 0.064-95.68-0.128-191.36 0.192-286.976C877.7632 574.592 874.8832 568.128 867.2672 561.792z" Fill="{Binding Path = Foreground, RelativeSource = { RelativeSource AncestorType ={ x:Type Label } }}" /> <Path Data="M1009.7312 495.808c-38.08-31.68-75.776-63.808-114.56-94.592-13.184-10.432-18.24-21.12-18.048-38.208 1.024-76.608 0.512-153.28 0.448-229.888 0-18.624-5.888-26.176-21.504-26.304-39.808-0.32-79.616-0.32-119.424 0-14.016 0.128-20.8 7.04-21.312 21.312-0.512 12.672-0.192 25.408-0.192 38.08 0 27.008 0 54.016 0 84.032-6.4-5.12-9.984-7.936-13.504-10.88-44.16-36.928-88.32-73.856-132.544-110.784C530.2432 96.256 493.9552 96.192 455.0432 128.576 374.0192 195.968 293.0592 263.488 212.0352 330.944 146.3712 385.664 80.7072 440.448 14.9792 495.168-4.0288 511.04-4.6688 519.04 11.5232 538.24c9.28 11.008 18.432 22.08 27.712 33.088 13.888 16.448 23.04 17.28 39.552 3.456 108.864-90.816 217.728-181.76 326.656-272.576C440.7712 272.704 476.2272 243.2 512.0032 213.376c35.712 29.76 70.848 59.008 105.92 88.256 109.184 91.136 218.432 182.272 327.616 273.408 16.32 13.632 25.408 12.672 39.424-3.968 9.536-11.328 19.008-22.72 28.544-34.048C1028.4192 519.296 1027.6512 510.72 1009.7312 495.808z" Fill="{Binding Path = Foreground, RelativeSource = { RelativeSource AncestorType ={ x:Type Label } }}" /> </Grid> </Viewbox>
4、接着在Icons枚举变量中加入新增的图标名称,图标资源的加载是通过枚举的名称来加载的,所以枚举变量的定义记得对应上对应的xaml文件名称。
namespace XamlIconDemo.Enums { public enum Icons { None, home, } }
5、接着编写XamlIcon.cs的代码,如下
public class XamlIcon : Label { Dictionary<string, Viewbox> globalIcon = new Dictionary<string, Viewbox>(); public Icons Icon { get { return (Icons)GetValue(IconProperty); } set { SetValue(IconProperty, value); } } public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(Icons), typeof(XamlIcon), new FrameworkPropertyMetadata(Icons.None, FrameworkPropertyMetadataOptions.AffectsArrange, new PropertyChangedCallback(IconChangedCallback))); public override void OnApplyTemplate() { base.OnApplyTemplate(); ReferenControls(); } public XamlIcon() { this.VerticalContentAlignment = VerticalAlignment.Center; this.HorizontalContentAlignment = HorizontalAlignment.Center; this.Padding = new Thickness(0); this.Margin = new Thickness(0); } private static void IconChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) { (d as XamlIcon).ReferenControls(); } public void ReferenControls() { if (Icon == Icons.None) { this.Content = null; return; } var iconStr = Icon.ToString(); var key = $"/XamlIconDemo;component/Resources/Icons/{iconStr}.xaml"; if (globalIcon.ContainsKey(key)) { this.Content = globalIcon[key]; } else { StreamResourceInfo info = Application.GetResourceStream(new Uri(key, UriKind.Relative)); using (var stream = info.Stream) { Viewbox page = (Viewbox)XamlReader.Load(info.Stream); this.Content = page; globalIcon.Add(key, page); } } } }
6、到这里自定义图标控件就基本完成了,接着测试是否可用,在主页添加自定义的控件
<Window x:Class="XamlIconDemo.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:ctls="clr-namespace:XamlIconDemo.Controls" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:XamlIconDemo" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <ctls:XamlIcon Icon="home" Height="50" Width="50" Foreground="Green" Margin="20"/> <ctls:XamlIcon Icon="home" Height="100" Width="100" Foreground="Red" Margin="20"/> <ctls:XamlIcon Icon="home" Height="200" Width="200" Foreground="Blue" Margin="20"/> </StackPanel> </Grid> </Window>
7、运行结果如下,可以看到图标已经成功显示出来了,并可以随意修改大小和填充色