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、运行结果如下,可以看到图标已经成功显示出来了,并可以随意修改大小和填充色

 

posted @ 2021-12-21 21:20  流浪g  阅读(1053)  评论(0编辑  收藏  举报