[WPF][Rubyer] 写一个自己的 UI 库 (二) – Icon

  • A+
所属分类:.NET技术
摘要

制作 WPF 的图标包,主要介绍从 iconfont 下载的图标包导入到 WPF 使用;Ruyber 下添加 自定义控件(WPF) Icon.cs、类 IconType.cs、类 IconDatas.cs


前言

制作 WPF 的图标包,主要介绍从 iconfont 下载的图标包导入到 WPF 使用;

1. 添加文件

Ruyber 下添加 自定义控件(WPF) Icon.cs、类 IconType.cs、类 IconDatas.cs

 

Rubyer.Themes 下添加 资源字典(WPF) Icon.xaml 

[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon

 

2.下载图标

iconfont 查找自己喜欢的图标包,浏览器 F12 => Console => 输入下列代码回车,添加所有图标到购物车

var span = document.querySelectorAll('.icon-cover'); for (var i = 0, len = span.length; i < len; i++) {      console.log(span[i].querySelector('span').click()); }

添加到项目

[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon

 

 

 下载到本地

[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon

 

 只解压 iconfont.ttf 到项目的 Assets 文件目录下

 [WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon

 

 

 

3.应用图标

在 BaseStyle.xaml 里添加标签

<!--IconFont-->     <FontFamily x:Key="IconFont" >         pack://application:,,,/Rubyer;component/Assets/#iconfont     </FontFamily>

回到刚刚  iconfont 的项目下,右键 F12 => Console => 输入下列代码回车,打印图标 名称 和 编码的对应的 json 数据

var allIcon = document.querySelectorAll('[class^=J_icon_id]'); var iconJson = []; console.log(allIcon[0].querySelector('.icon-name').innerHTML) for (var i = 0, len = allIcon.length; i < len; i++) {      iconJson[i] = ({'name':allIcon[i].querySelector('.icon-name').innerHTML,'code':allIcon[i].querySelector('.icon-code').innerHTML});  } console.log(iconJson)

打印完右键 json 变量 => store as global variable, 生成 temp1,输入 copy(temp1),拷贝整个 json 数据,创建文本文件粘贴 到 内容; 保存文件

[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon

 

 

 新建一个控制台项目,添加 JsonObject.cs 类

public class JsonObject {     public string Name { get; set; }     public string Code { get; set; } }

Program.cs 读取刚刚添加的 文本文件 到  List<JsonObject>,打印内容全部拷贝 粘贴 到  IconType.cs,为所有图标名称的枚举类型  

      /// <summary>         /// 从文件加载到对象         /// </summary>         /// <typeparam name="T">对象类型</typeparam>         /// <param name="fileName">文件名路径</param>         /// <returns></returns>         public static T LoadFile2Object<T>(string fileName)         {            try             {                 string json = File.ReadAllText(fileName);                 return JsonConvert.DeserializeObject<T>(json);             }             catch (Exception)             {                 return default(T);             }           }  class Program     {         static void Main(string[] args)         {             var jsonObject = LoadFile2Object<List<JsonObject>>("IconJson.txt");              #region 添加 IconType             int count = 0;             foreach (var item in jsonObject)             {                 //Console.WriteLine($"name:{item.Name},code:{item.Code}");                 var names = item.Name.Trim().Split(' ', '-');                 var name = "";                 for (int i = 0; i < names.Length; i++)                 {                     if (names[i] == " " || names[i] == "") continue;                     name += names[i].Substring(0, 1).ToUpper() + names[i].Substring(1);                 }                 count++;                 Console.WriteLine($"{name},");             }             #endregion              Console.ReadLine();         }     }

IconType.cs:

public enum IconType {     BookMinus,     Cookie,     FormatBold,     LedOutline,     Pin,     Speedometer,     Web,     BookMultiple,     Copyright,     ... }

注释掉上面    #region 添加 IconType 的内容,换成下面的代码, 打印出  IconDatas.cs 的内容, 打印内容全部拷贝 粘贴 到  IconDatas.cs,为枚举对应的图标代码 

 #region 添加 IconDatas             int count = 0;             foreach (var item in jsonObject)             {                 var names = item.Name.Trim().Split(' ', '-');                 var name = "";                 var code = item.Code.Replace("&amp;#x", "\u").Replace(";", "");                 for (int i = 0; i < names.Length; i++)                 {                     if (names[i] == " " || names[i] == "") continue;                     name += names[i].Substring(0, 1).ToUpper() + names[i].Substring(1);                 }                 count++;                 //{ IconType.SafetyCertificate, "ue7f5"}                 Console.WriteLine($"{{ IconType.{name},"{code}"}},");             }             #endregion

IconDatas.cs:

namespace Rubyer {     internal class IconDatas     {         public static Dictionary<IconType, string> GetAll() =>             new Dictionary<IconType, string>             {                 { IconType.BookMinus,"ue6db"},                 { IconType.Cookie,"ue7db"},                 { IconType.FormatBold,"ue8db"},                 { IconType.LedOutline,"ue9db"},                 { IconType.Pin,"ueadb"},                 { IconType.Speedometer,"uebdb"},                 { IconType.Web,"uecdb"},                 { IconType.BookMultiple,"ue6dc"},                 { IconType.Copyright,"ue7dc"},                         ...             }         } }

 

4.修改模板

Icon.xaml:WPF 没有 Icon 控件,自己定义一个模板样式

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     xmlns:rubyer="clr-namespace:Rubyer">     <ResourceDictionary.MergedDictionaries>         <ResourceDictionary Source="pack://application:,,,/Rubyer;component/Themes/BaseStyle.xaml" />     </ResourceDictionary.MergedDictionaries>          <Style TargetType="{x:Type rubyer:Icon}">         <Setter Property="Height" Value="20"/>         <Setter Property="Width" Value="20"/>         <Setter Property="IsTabStop" Value="False"/>         <Setter Property="HorizontalAlignment" Value="Left"/>         <Setter Property="VerticalAlignment" Value="Top"/>         <Setter Property="Template">             <Setter.Value>                 <ControlTemplate TargetType="{x:Type rubyer:Icon}">                     <Border Background="{TemplateBinding Background}"                             BorderBrush="{TemplateBinding BorderBrush}"                             BorderThickness="{TemplateBinding BorderThickness}">                         <Viewbox>                             <TextBlock FontFamily="{StaticResource IconFont}"                                         Text="{Binding Code,RelativeSource={RelativeSource TemplatedParent}}"                                        Foreground="{TemplateBinding Foreground}"/>                         </Viewbox>                     </Border>                 </ControlTemplate>             </Setter.Value>         </Setter>     </Style> </ResourceDictionary>

主要图标应用位置,Text 绑定 iconfont 图标的编码:

<TextBlock FontFamily="{StaticResource IconFont}" Text="{Binding Code,RelativeSource={RelativeSource TemplatedParent}}" Foreground="{TemplateBinding Foreground}"/>

Icon.cs : 自定义控件 的内容;

public class Icon : Control     {         // 所有图标键值对         private static readonly Lazy<Dictionary<IconType, string>> _codes = new Lazy<Dictionary<IconType, string>>(IconDatas.GetAll());          static Icon()         {             DefaultStyleKeyProperty.OverrideMetadata(typeof(Icon), new FrameworkPropertyMetadata(typeof(Icon)));         }          public override void OnApplyTemplate()         {             base.OnApplyTemplate();             UpdateIcon();         }          // 图标类型         public IconType Type         {             get { return (IconType)GetValue(TypeProperty); }             set { SetValue(TypeProperty, value); }         }          public static readonly DependencyProperty TypeProperty =             DependencyProperty.Register("Type", typeof(IconType), typeof(Icon), new PropertyMetadata(default(IconType), TypePropertyChangedCallBack));          private static void TypePropertyChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)         {             ((Icon)d).UpdateIcon();         }          // 图标编码         public string Code         {             get { return (string)GetValue(CodeProperty); }             set { SetValue(CodeProperty, value); }         }          public static readonly DependencyProperty CodeProperty =             DependencyProperty.Register("Code", typeof(string), typeof(Icon), new PropertyMetadata(""));           // 更新图标         private void UpdateIcon()         {             string code = null;             _codes.Value?.TryGetValue(Type, out code);             Code = code;         }     }

 

5.应用

在 Rubyer,引用 Icon.xaml

<ResourceDictionary.MergedDictionaries>         <ResourceDictionary Source="pack://application:,,,/Rubyer;component/Themes/Button.xaml" />         <ResourceDictionary Source="pack://application:,,,/Rubyer;component/Themes/Icon.xaml" />     </ResourceDictionary.MergedDictionaries>

 

回到 RubyerDemo ,尝试使用 Icon 控件,Type 属性 可以提示I con 枚举所有类型

<Button Style="{DynamicResource CircleMidButton}">     <rubyer:Icon Type="Qqchat"/> </Button> <Button Style="{DynamicResource CircleLightButton}" rubyer:ButtonHelper.CircleDima="40">     <rubyer:Icon Type="Wechat" Height="30" Width="30"/> </Button> <Button Style="{DynamicResource CircleDarkButton}" rubyer:ButtonHelper.CircleDima="50">     <rubyer:Icon Type="GithubCircle" Height="40" Width="40"/> </Button> <Button Style="{DynamicResource CircleAccentButton}" rubyer:ButtonHelper.CircleDima="60">     <rubyer:Icon Type="Cookie" Height="50" Width="50"/> </Button>

 

最后,附图

[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon