原文:对XAML进行编辑的辅助类(XamlHelper)

// XamlHelper.cs
// --------------------------------------------
// 对XAML进行编辑操作的辅助类:
// 对选中的XAML进行操作; 对XAML代码进行对齐整理; 对XAML标记进行着色显示等
// --------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Collections;
using System.Windows;
using System.IO;
using System.Xml;
using System.Windows.Markup;

namespace BrawDraw.Com.Xaml.Utility
{

    /// <summary>
    /// Provides help functions for processing XAML.
    /// </summary>
    public class XamlHelper
    {
        /// <summary>
        /// Get XAML from TextRange.Xml property
        /// </summary>
        /// <param name="range">TextRange</param>
        /// <returns>return a string serialized from the TextRange</returns>
        public static string GetTextRangeXaml(TextRange range)
        {
            MemoryStream mstream;

            if (range == null)
            {
                throw new ArgumentNullException("range");
            }

            mstream = new MemoryStream();
            range.Save(mstream, DataFormats.Xaml);

            //must move the stream pointer to the beginning since range.save() will move it to the end.
            mstream.Seek(0, SeekOrigin.Begin);

            //Create a stream reader to read the xaml.
            StreamReader stringReader = new StreamReader(mstream);

            return stringReader.ReadToEnd();
        }

        /// <summary>
        /// Set XML to TextRange.Xml property.
        /// </summary>
        /// <param name="range">TextRange</param>
        /// <param name="xaml">XAML to be set</param>
        public static void SetTextRangeXaml(TextRange range, string xaml)
        {
            MemoryStream mstream;
            if (null == xaml)
            {
                throw new ArgumentNullException("xaml");
            }
            if (range == null)
            {
                throw new ArgumentNullException("range");
            }

            mstream = new MemoryStream();
            StreamWriter sWriter = new StreamWriter(mstream);

            mstream.Seek(0, SeekOrigin.Begin); //this line may not be needed.
            sWriter.Write(xaml);
            sWriter.Flush();

            //move the stream pointer to the beginning.
            mstream.Seek(0, SeekOrigin.Begin);

            range.Load(mstream, DataFormats.Xaml);
        }

        /// <summary>
        /// Parse a string to WPF object.
        /// </summary>
        /// <param name="str">string to be parsed</param>
        /// <returns>return an object</returns>
        public static object ParseXaml(string str)
        {
            MemoryStream ms = new MemoryStream(str.Length);
            StreamWriter sw = new StreamWriter(ms);
            sw.Write(str);
            sw.Flush();

            ms.Seek(0, SeekOrigin.Begin);

            ParserContext pc = new ParserContext();

            pc.BaseUri = new Uri(System.Environment.CurrentDirectory + "/");

            return XamlReader.Load(ms, pc);
        }

        public static string IndentXaml(string xaml)
        {
            //open the string as an XML node
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xaml);
            XmlNodeReader nodeReader = new XmlNodeReader(xmlDoc);

            //write it back onto a stringWriter
            System.IO.StringWriter stringWriter = new System.IO.StringWriter();
            System.Xml.XmlTextWriter xmlWriter = new System.Xml.XmlTextWriter(stringWriter);
            xmlWriter.Formatting = System.Xml.Formatting.Indented;
            xmlWriter.Indentation = 4;
            xmlWriter.IndentChar = ' ';
            xmlWriter.WriteNode(nodeReader, false);

            string result = stringWriter.ToString();
            xmlWriter.Close();

            return result;
        }

        public static string RemoveIndentation(string xaml)
        {
            if (xaml.Contains("/r/n    "))
            {
                return RemoveIndentation(xaml.Replace("/r/n    ", "/r/n"));
            }
            else
            {
                return xaml.Replace("/r/n", "");
            }
        }

        public static string ColoringXaml(string xaml)
        {
            string[] strs;
            string value = "";
            string s1, s2;
            s1 = "<Section xml:space=/"preserve/" xmlns=/"http://schemas.microsoft.com/winfx/2006/xaml/presentation/"><Paragraph>";
            s2 = "</Paragraph></Section>";

            strs = xaml.Split(new char[] { '<' });
            for (int i = 1; i < strs.Length; i++)
            {
                value += ProcessEachTag(strs[i]);
            }
            return s1 + value + s2;
        }

        static string ProcessEachTag(string str)
        {
            string front = "<Run Foreground=/"Blue/">&lt;</Run>";
            string end = "<Run Foreground=/"Blue/">&gt;</Run>";
            string frontWithSlash = "<Run Foreground=/"Blue/">&lt;/</Run>";
            string endWithSlash = "<Run Foreground=/"Blue/"> /&gt;</Run>";//a space is added.
            string tagNameStart = "<Run FontWeight=/"Bold/">";
            string propertynameStart = "<Run Foreground=/"Red/">";
            string propertyValueStart = "/"<Run Foreground=/"Blue/">";
            string endRun = "</Run>";
            string returnValue;
            string[] strs;
            int i = 0;

            if (str.StartsWith("/"))
            {   //if the tag is an end tag, remove the "/"
                returnValue = frontWithSlash;
                str = str.Substring(1).TrimStart();
            }
            else
            {
                returnValue = front;
            }
            strs = str.Split(new char[] { '>' });
            str = strs[0];
            i = (str.EndsWith("/")) ? 1 : 0;

            str = str.Substring(0, str.Length - i).Trim();

            if (str.Contains("="))//the tag has a property
            {
                //set tagName
                returnValue += tagNameStart + str.Substring(0, str.IndexOf(" ")) + endRun + " ";
                str = str.Substring(str.IndexOf(" ")).Trim();
            }
            else //no property
            {
                returnValue += tagNameStart + str.Trim() + endRun + " ";
                //nothing left to parse
                str = "";
            }

            //Take care of properties:
            while (str.Length > 0)
            {
                returnValue += propertynameStart + str.Substring(0, str.IndexOf("=")) + endRun + "=";
                str = str.Substring(str.IndexOf("/"") + 1).Trim();
                returnValue += propertyValueStart + str.Substring(0, str.IndexOf("/"")) + endRun + "/" ";
                str = str.Substring(str.IndexOf("/"") + 1).Trim();
            }

            if (returnValue.EndsWith(" "))
            {
                returnValue = returnValue.Substring(0, returnValue.Length - 1);
            }

            returnValue += (i == 1) ? endWithSlash : end;

            //Add the content after the ">"
            returnValue += strs[1];

            return returnValue;
        }
    }
}
 

对XAML进行编辑的辅助类(XamlHelper)的更多相关文章

  1. wpf xaml文件编辑出现中文乱码

    突然有一天,发现在xaml文件编辑窗里打汉字出来了乱码...抓狂 结果发现是番茄助手搞得鬼.只能在编辑xaml文件是暂时关闭番茄助手 visual assist

  2. WPF入门教程系列十九——ListView示例(一)

    经过前面的学习,今天我做一个比较综合的WPF程序示例,主要包括以下功能: 1) 查询功能.从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,然后展示到WPF的Windo ...

  3. WPF 杂谈——入门介绍

    对于WPF的技术笔者是又爱又恨.现在WPF的市场并不是很锦气.如果以WPF来吃饭的话,只怕会饿死在街头.同时现在向面WEB开发更是如火冲天.所以如果是新生的话,最好不要以WPF为主.做为选择性来学习一 ...

  4. Blend 2015 教程 (五) 自定义状态

    本篇再补充一块内容,就是自定义状态的介绍. 自定义状态用于封装用户控件在各种状态之间切换时的外观变化及其动画效果,方便调用.比如有个用户控件用于实现类似舞台幕布打开和关闭切换的效果,可以创建幕布关闭和 ...

  5. UWP 播放媒体控件

    最近我的uwp需要有一个有声朗读的功能,like this 点击声音按钮就可以有声朗读了.这里主要是用了媒体播放的控件. 一般我们把需求分为两种: 一种是不需要呈现播放器的样子,只需要用户点击一下别的 ...

  6. WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮

    原文:WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮 在边框中加入一些元素,在应用程序的界面设计中,已经开始流行起来.特别是在浏览器(Crome,IE,Firefox,Opera)中都有应用. ...

  7. [MAUI] 在.NET MAUI中结合Vue实现混合开发

    ​ 在MAUI微软的官方方案是使用Blazor开发,但是当前市场大多数的Web项目使用Vue,React等技术构建,如果我们没法绕过已经积累的技术,用Blazor重写整个项目并不现实. Vue是当前流 ...

  8. VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法。

    原文:VS编程,编辑WPF过程中,点击设计器中界面某一控件,在XAML中高亮突出显示相应的控件代码的设置方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net ...

  9. vs.net2017在编辑的wpf的xaml文件引用本程序集下的类提示“找不到”

    local对应就是当前exe程序下的类,会提示“...命令空间...找不到...” 因为我调整过生成的,于是尝试调回来anyCPU 问题解决. 看了一下vs.net2017的所在目录"C:\ ...

随机推荐

  1. [AngularFire 2] Joins in Firebase

    Lets see how to query Firebase. First thing, when we do query, 'index' will always help, for both SQ ...

  2. C# .NET Socket

    C# .NET Socket 简单实用框架 背景: 首先向各位前辈,大哥哥小姐姐问一声好~ 这是我第一次写博客,目前为一个即将步入大四的学生,上学期在一家公司实习了半年,后期发现没有动力,而且由于薪水 ...

  3. css聊天气泡样式

    https://files.cnblogs.com/files/zonglonglong/%E8%81%8A%E5%A4%A9%E6%B0%94%E6%B3%A1.zip

  4. rabbitmq.config详细配置参数

    原文:rabbitmq.config详细配置参数 rabbitmq.config详细配置参数 详细使用方法请点击:http://blog.csdn.net/Super_RD/article/detai ...

  5. php获取调用本方法的上个方法,php堆栈,函数入库

    $array =debug_backtrace(); //print_r($array);//信息很齐全 unset($array[0]); foreach($array as $row) { $ht ...

  6. [Angular Testing] Unit Testing -- Test component and service.

    Recommend to use angular-cli to generate component and service, so we can get testing templates. ng ...

  7. pycharm的集成vim

    pycharm的集成vim 1. 基本使用 激活码 BIG3CLIK6F-eyJsaWNlbnNlSWQiOiJCSUczQ0xJSzZGIiwibGljZW5zZWVOYW1lIjoibGFuIHl ...

  8. 【codeforces 754D】Fedor and coupons

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. 【codeforces 755D】PolandBall and Polygon

    time limit per test4 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  10. js进阶 9-10 html控件如何实现点击自动选择控件内容

    js进阶 9-10  html控件如何实现点击自动选择控件内容 一.总结 一句话总结: 1.在click事件中,如果focus,那就select 2.blur 1.html中控件添加两种方式? 在表单 ...