[WPF][Rubyer] 写一个自己的 UI 库 (二) - Icon
前言
制作 WPF 的图标包,主要介绍从 iconfont 下载的图标包导入到 WPF 使用;
1. 添加文件
Ruyber 下添加 自定义控件(WPF) Icon.cs、类 IconType.cs、类 IconDatas.cs
Rubyer.Themes 下添加 资源字典(WPF) Icon.xaml
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());
}
添加到项目
下载到本地
只解压 iconfont.ttf 到项目的 Assets 文件目录下
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 数据,创建文本文件粘贴 到 内容; 保存文件
新建一个控制台项目,添加 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 = ;
foreach (var item in jsonObject)
{
//Console.WriteLine($"name:{item.Name},code:{item.Code}");
var names = item.Name.Trim().Split(' ', '-');
var name = "";
for (int i = ; i < names.Length; i++)
{
if (names[i] == " " || names[i] == "") continue;
name += names[i].Substring(, ).ToUpper() + names[i].Substring();
}
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 = ;
foreach (var item in jsonObject)
{
var names = item.Name.Trim().Split(' ', '-');
var name = "";
var code = item.Code.Replace("&#x", "\\u").Replace(";", "");
for (int i = ; i < names.Length; i++)
{
if (names[i] == " " || names[i] == "") continue;
name += names[i].Substring(, ).ToUpper() + names[i].Substring();
}
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的更多相关文章
- 自己动手写一个iOS 网络请求库的三部曲[转]
代码示例:https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary 开源项目:Pitaya,适合大 ...
- WPF MVVM 写一个健壮的INotifyPropertyChanged基类
当我们用MVVM的时候要实现INotifyPropertyChanged,如果你是基于.net4.5以下的framework(.net4.5已有新特性我这里就不说了) 你很可能会这么写 public ...
- 【写一个自己的js库】 2.实现自己的调试日志
还是本着学习的目的,实现一个自己的调试日志,界面很简单,就是将调试信息显示在页面的正中央,用一个ul包裹,每条信息就是一个li. 1.新建一个myLogger.js文件,将需要的方法声明一下.其中va ...
- 【写一个自己的js库】 1.搭个架子先
最近在看<javascript dom 高级程序设计>,想着跟着里面的代码敲一遍吧,也算是做一下学习笔记吧,所以这不是重新发明轮子,只是个学习的过程. 1.先确定自己的命名空间,并且加入几 ...
- 如何写一个自己的组件库,打成NPM包,并上传到NPM远程
1.首先使用vue create my_project 构建一个自己的Vue项目 2.vue.config.js和package.json配置如下,做了些修改 const path = require ...
- 【写一个自己的js库】 5.添加修改样式的方法
1.根据id或class或tag修改样式,样式名是-连接格式的. function setStyleById(elem, styles){ if(!(elem = $(elem)) return fa ...
- 【写一个自己的js库】 3.添加几个处理字符串的方法
1.生成重复的字符串 if(!String.repeat){ String.prototype.repeat = function (count){ return new Array(count + ...
- 【写一个自己的js库】 4.完善跨浏览器事件操作
1.阻止冒泡. function stopPropagation(event){ event = event || getEvent(event); if(event.stopPropagation) ...
- Cocos2D iOS之旅:如何写一个敲地鼠游戏(二):Cocos2D中的高清支持
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
随机推荐
- 图表可视化seaborn风格和调色盘
seaborn是基于matplotlib的python数据可视化库,提供更高层次的API封装,包括一些高级图表可视化等工具. 使用seaborn需要先安装改模块pip3 install seaborn ...
- 读/写xlsx文件
安装 pip install openpyxl 1.创建Excel电子表格 建立新文档需要调用Workbook对象的save方法,一个Workbook对象代表一个Excel工作簿,该方法的参数是保存的 ...
- pandas_分类与聚合
# 分组与聚合 import pandas as pd import numpy as np # 设置列对齐 pd.set_option("display.unicode.ambiguous ...
- Python os.close() 方法
概述 os.close() 方法用于关闭指定的文件描述符 fd.高佣联盟 www.cgewang.com 语法 close()方法语法格式如下: os.close(fd); 参数 fd -- 文件描述 ...
- PHP date_parse() 函数
------------恢复内容开始------------ 实例 返回一个包含指定日期的详细信息的关联数组: <?phpprint_r(date_parse("2013-05-01 ...
- PyCharm2020激活破解教程
本文内容皆为作者原创,如需转载,请注明出处:https://www.cnblogs.com/xuexianqi/p/12767075.html 免责声明:本方法只做学习研究之用,不得用于商业用途 若经 ...
- 职场老鸟,一文教你如何正确入门Python爬虫!
爬虫现在的火热程度我就不说了,先说一下这门技术能干什么事儿,主要为以下三方面: 1.爬取数据,进行市场调研和商业分析 爬取知乎.豆瓣等网站的优质话题内容:抓取房产网站买卖信息,分析房价变化趋势.做不同 ...
- JAVA程序设计环境
JDK ,Java Development Kit(Java开发工具包) JRE ,Java Runtime Environment(Java运行时环境) SE ,Standard Edition ...
- 嵌入式linux系统应用开发
关于嵌入式系统 平时大家说的嵌入式其实范围比较广的,是一种软硬件可裁剪,以应用为中心开发的专用系统,硬件平台可以是单片机,或者以ARM系列的处理器.单片机一般直接裸奔程序,不过现在有了好多基于单片 ...
- 简单认识JAVA内存划分
Java的内存划分为五个部分 那么又是哪五个部分呢?跟着我往下看! 介绍: 每个程序运行都需要内存空间,所以Java也不例外:而Java把从计算机中申请的这一块内存又进行了划分!而所在目的是为了让程序 ...