WPF中使用阿里巴巴矢量图标-将IconFont转为TextBlock样式

139 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

Model

 /// <summary>
    ///
    /// </summary>
    public class IconFont
    {
        /// <summary>
        ///
        /// </summary>
        public string Class { get; set; }

        /// <summary>
        ///
        /// </summary>
        public List<Li> Li { get; set; } = new List<Li>();
    }
  /// <summary>
    /// Li
    /// </summary>
    public class Li
    {
        /// <summary>
        /// Class
        /// </summary>
        public string Class { get; set; }

        /// <summary>
        /// Span
        /// </summary>
        public Content Span { get; set; } = new Content();

        /// <summary>
        /// Div
        /// </summary>
        public List<Content> Div { get; set; } = new List<Content>();
    }
    /// <summary>
    ///
    /// </summary>
    public class Content
    {
        /// <summary>
        ///
        /// </summary>
        [Description("Class")]
        public string Class { get; set; }

        /// <summary>
        ///
        /// </summary>
        [Description("Text")]
        public string Text { get; set; }
    }

Method

/// <summary>
        /// html文件转style
        /// </summary>
        /// <param name="name">style名称</param>
        /// <param name="styleBase">style基类信息</param>
        /// <param name="isOpenFolder">是否打开文件夹</param>
        /// <param name="func">icon文件名处理方法</param>
        public static void GetStyleFromHtml(string name, StyleBase styleBase = null, bool isOpenFolder = true, Func<string, string> func = null)
        {
            var htmlPath = FileUtil.GetFilesFullName(false, filter: "HTML文件(*.html) | *.html", title: "请选择demo_index.html文件").FirstOrDefault();
            if (!string.IsNullOrEmpty(htmlPath))
            {
                var doc = new HtmlDocument();
                doc.Load(htmlPath);
                var htmlNodes = doc.DocumentNode.SelectNodes("//body/div/div[last()]/div[1]/ul[1]").FirstOrDefault();/*/ul[last()-1]*/
                var str = new StringBuilder();
                str.AppendLine(" <ul class=\"icon_lists dib - box\">");
                str.AppendLine(htmlNodes.InnerHtml);
                str.Append("</ul>");
                var xml = new XmlDocument();
                xml.LoadXml(str.ToString());
                SaveStyle(name, xml, styleBase, isOpenFolder, func);
            }
        }

        /// <summary>
        ///保存样式
        /// </summary>
        /// <param name="name">样式名,输出样式名为name+TextBlockStyles</param>
        /// <param name="xml">阿里Iconxml文件</param>
        /// <param name="styleBase">基样式</param>
        /// <param name="isOpenFolder">是否打开保存样式的文件夹</param>
        /// <param name="func">icon文件名处理方法</param>
        private static void SaveStyle(string name, XmlDocument xml, StyleBase styleBase = null, bool isOpenFolder = true, Func<string, string> func = null)
        {
            #region

            var style = new StringBuilder();
            style.AppendLine("<ResourceDictionary xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"");
            style.AppendLine("xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\">");
            if (styleBase is null)
            {
                //
            }
            else
            {
                if (string.IsNullOrWhiteSpace(styleBase.BasePath) && string.IsNullOrWhiteSpace(styleBase.NavigationBasePath))
                {
                    //
                }
                else
                {
                    style.AppendLine("<ResourceDictionary.MergedDictionaries>");
                    style.AppendLine(string.IsNullOrWhiteSpace(styleBase.BasePath) ?
                        styleBase.BasePath :
                        $"<ResourceDictionary Source=\"{styleBase.BasePath}\"/>");
                    style.AppendLine(!string.IsNullOrWhiteSpace(styleBase.NavigationBasePath) && styleBase.NavigationBasePath != styleBase.BasePath ?
                        $"<ResourceDictionary Source=\"{styleBase.BasePath}\"/>" :
                        string.Empty);
                    style.AppendLine("</ResourceDictionary.MergedDictionaries>");
                }
            }
            style.AppendLine(JsonConvert.SerializeXmlNode(xml, Newtonsoft.Json.Formatting.None, true).ToALiIconFont().ToStyle(
                name,
                styleBase == null ? string.Empty : styleBase.BaseName,
                styleBase == null ? string.Empty : styleBase.NavigationBaseName,
                func,
                styleBase == null ? string.Empty : styleBase.NavigationPrefix
                ));
            style.Append("</ResourceDictionary>");
            var directoryPath = Path.Combine(FileUtil.GetDirectory(), $"{name}TextBlockStyles{DateTime.Now:yyyyMMddHHmmss}");

            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
            File.WriteAllText(Path.Combine(directoryPath, $"{name}TextBlockStyles.xaml"), style.ToString());
            if (isOpenFolder)
            {
                Process.Start(directoryPath);
            }
            #endregion
        }

        /// <summary>
        /// IconFont转TextBlock样式
        /// </summary>
        /// <param name="iconFont">阿里IconFont</param>
        /// <param name="name">样式文件</param>
        /// <param name="baseStyleName">基样式名</param>
        /// <param name="navigationBaseStyleName">导航栏Icon基样式名</param>
        ///  <param name="func">文件名处理方法</param>
        /// <param name="prefix">导航栏Icon文件名前缀</param>
        /// <returns></returns>
        public static string ToStyle(this IconFont iconFont, string name, string baseStyleName, string navigationBaseStyleName = "", Func<string, string> func = null, string prefix = "")
        {
            StringBuilder style = new StringBuilder();
            _ = style.AppendLine($"<Style x:Key=\"{name}IconFontBaseStyle\"");
            _ = style.AppendLine("TargetType=\"TextBlock\"");

            if (!string.IsNullOrEmpty(baseStyleName))
            {
                _ = style.Append("BasedOn=\"{StaticResource ");
                _ = style.Append(baseStyleName);
                _ = style.AppendLine("}\"");
            }
            _ = style.Remove(style.Length - 2, 2);
            _ = style.AppendLine(">");
            _ = style.AppendLine("<Setter Property=\"FontFamily\" Value=\"/Resources/#iconfont\"/>");
            _ = style.AppendLine("</Style>");
            foreach (Li li in iconFont.Li.OrderBy(li => li.Div.FirstOrDefault().Text))
            {
                _ = func == null ? style.AppendLine($"<Style x:Key=\"{li.Div.FirstOrDefault().Text}TextBlockStyle\"") : style.AppendLine($"<Style x:Key=\"{func(li.Div.FirstOrDefault().Text) }TextBlockStyle\"");
                _ = style.AppendLine("TargetType=\"TextBlock\"");
                _ = style.Append("BasedOn=\"{StaticResource ");
                _ = string.IsNullOrEmpty(prefix) ? style.Append($"{name}IconFontBaseStyle") : li.Div.FirstOrDefault().Text.Contains(prefix) ? style.Append(navigationBaseStyleName) : style.Append($"{name}IconFontBaseStyle");
                _ = style.AppendLine("}\">");
                _ = style.AppendLine($"<Setter Property=\"Text\" Value=\"{ li.Div.LastOrDefault().Text}\"/>");
                _ = style.AppendLine("</Style>");
            }
            return style.ToString();
        }