1. 程式人生 > 其它 >WPF開發隨筆收錄-自定義圖示XamlIcon

WPF開發隨筆收錄-自定義圖示XamlIcon

一、前言

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、執行結果如下,可以看到圖示已經成功顯示出來了,並可以隨意修改大小和填充色