[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 ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
随机推荐
- 深度搜索---------Lake counting
#include<iostream>#include<cstdio>#include<cstdlib>#define maxn 100char ch[maxn][m ...
- windows系统远程修改密码
1.需求:公司需要短时间.批量修改一些windows系统的管理员密码: 2.准备工作: a.下载软件:链接:https://pan.baidu.com/s/1kV52DqE1_4siPuxS5Mosc ...
- netcore RabbitMQ入门--win10开发环境
安装 1.进入rabbitMQ官网下载安装包 2.点击安装包安装的时候会提示需要先装erlang 点击是会自动跳转到erlang的下载界面如果没有跳转可以直接点击这里下载,根据系统选择下载包 下载完之 ...
- 重学c#系列——非托管实例(五)
前言 托管资源到是好,有垃圾回收资源可以帮忙,即使需要我们的一些小小的调试来优化,也是让人感到欣慰的.但是非托管资源就显得苍白无力了,需要程序员自己去设计回收,同样有设计的地方也就能体现出程序员的设计 ...
- MongoDB副本集部署
mongodb 副本集搭建 环境192.168.1.191 master192.168.1.192 slave,arbiterOS: ubuntu14.04mongodb: mongodb-l ...
- list 和 [ ] 的功能不相同
对于一个对象: list(对象) 可以进行强制转换 [对象] 不能够进行强制转换,只是在外围加上 [ ] 列表推导式中相同 2020-05-06
- Unity 笔记
摄像机 Main Camera 跟随主角移动,不看 UI 剧情摄像机 当进入剧情时,可以关闭 main camera,启用剧情摄像机,不看 UI UI 摄像机 看 UI Unity编辑器常用的sett ...
- MyBatisPlus性能分析插件,条件构造器,代码自动生成器详解
性能分析插件 我们在平时的开发中,会遇到一些慢sql,测试,druid MP(MyBatisPlus)也提供性能分析插件,如果超过这个时间就停止 不过官方在3.2版本的时候取消了,原因如下 条件构造器 ...
- Linux(Centos 7)下安装Git并配置连接GitHub
1.安装git Centos7 查看git --version 2.配置用户名密码 git config --global user.name "xxx" git config ...
- windows系统下python setup.py install ---出现cl问题,cpp_extension.py:237: UserWarning: Error checking compiler version for cl: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte
将cpp_extension.py文件中的 原始的是 compiler_info.decode() try: if sys.platform.startswith('linux'): minimu ...