原文:对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. ios获取系统时间

    //获取系统时间 NSDate * date=[NSDate date]; NSDateFormatter *dateformatter=[[NSDateFormatter alloc] init]; ...

  2. 关于Android中设置闹钟的相对比较完善的解决方案

    我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这里写的这个demo抽出来了封装了一个类库,大家直接调用其中的设置闹钟和取消闹钟的 ...

  3. or小计

    1.使用or的时候,必须养成两边添加括号,否则结果完全不一样. 2.or条件如果复杂的情况下,可以适当考虑union all改写.

  4. [Tools] Fix Only Committed Files with Prettier and lint-staged

    In this lesson we'll use prettier and lint-staged to run prettier only on files that have been chang ...

  5. hprof教程 分类: B1_JAVA 2015-03-02 12:18 444人阅读 评论(0) 收藏

    大部分内容参考http://www.linuxidc.com/Linux/2012-04/58178.htm J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profili ...

  6. 【计算机】基本概念的理解 —— 沙盒(sandbox)、交互式计算/编程/应用

    web scraper:网络铲: scraper:n. 刮刀:铲土机:守财奴: 1. 交互式计算/编程/应用(interactive computing/application/programming ...

  7. [React] Cleanly Map Over A Stateless Functional Component with a Higher Order Component

    In this lesson we'll create a Higher Order Component (HOC) that takes care of the key property that ...

  8. boost::any的一般使用方法

    01.#include <iostream>    02.#include <list>    03.#include <boost/any.hpp>    04. ...

  9. ios开发知识点补充

    一:self class,self superClass  super class  super superClass 的区别 新建SubPerson继承person,在SubPerson中打印如下: ...

  10. Notepad++打开xml文件显示crlf的问题

    如图所示,显示CRLF,  CRLF其实是换行符. 所以在下图所示设置下显示行尾符不显示即可.