在UWP中使用T4的注意事项

在UWP中尝试使用T4的朋友们可能会注意到,VS设计器默认生成的运行时T4无法通过编译,因为他使用了一些不支持UWP的API,解决方案也很简单,知道将其复制出来,修正不兼容的部分,指定inherits参数为新的基类即可,这里提供一个简单的版本,应该还可以优化

public class FormatterBase
    {
        private bool _endsWithNewline;
        private StringBuilder _generationEnvironmentField;
        private List<int> _indentLengthsField;

protected StringBuilder GenerationEnvironment
        {
            get
            {
                if ((_generationEnvironmentField == null))
                {
                    _generationEnvironmentField = new StringBuilder();
                }
                return _generationEnvironmentField;
            }
            set { _generationEnvironmentField = value; }
        }

/// <summary>
        ///     A list of the lengths of each indent that was added with PushIndent
        /// </summary>
        private List<int> IndentLengths
        {
            get
            {
                if ((_indentLengthsField == null))
                {
                    _indentLengthsField = new List<int>();
                }
                return _indentLengthsField;
            }
        }

/// <summary>
        ///     Gets the current indent we use when adding lines to the output
        /// </summary>
        public string CurrentIndent { get; private set; } = "";

/// <summary>
        ///     Current transformation session
        /// </summary>
        public virtual IDictionary<string, object> Session { get; set; }

public virtual string TransformText()
        {
            GenerationEnvironment.Clear();
            Render();
            return string.Empty;
        }

protected virtual void Render()
        {
        }

#region Transform-time helpers

/// <summary>
        ///     Write text directly into the generated output
        /// </summary>
        public void Write(string textToAppend)
        {
            if (string.IsNullOrEmpty(textToAppend))
            {
                return;
            }
            // If we‘re starting off, or if the previous text ended with a newline,
            // we have to append the current indent first.
            if (((GenerationEnvironment.Length == 0)
                 || _endsWithNewline))
            {
                GenerationEnvironment.Append(CurrentIndent);
                _endsWithNewline = false;
            }
            // Check if the current text ends with a newline
            if (textToAppend.EndsWith(Environment.NewLine, StringComparison.CurrentCulture))
            {
                _endsWithNewline = true;
            }
            // This is an optimization. If the current indent is "", then we don‘t have to do any
            // of the more complex stuff further down.
            if ((CurrentIndent.Length == 0))
            {
                GenerationEnvironment.Append(textToAppend);
                return;
            }
            // Everywhere there is a newline in the text, add an indent after it
            textToAppend = textToAppend.Replace(Environment.NewLine, (Environment.NewLine + CurrentIndent));
            // If the text ends with a newline, then we should strip off the indent added at the very end
            // because the appropriate indent will be added when the next time Write() is called
            if (_endsWithNewline)
            {
                GenerationEnvironment.Append(textToAppend, 0, (textToAppend.Length - CurrentIndent.Length));
            }
            else
            {
                GenerationEnvironment.Append(textToAppend);
            }
        }

/// <summary>
        ///     Write text directly into the generated output
        /// </summary>
        public void WriteLine(string textToAppend)
        {
            Write(textToAppend);
            GenerationEnvironment.AppendLine();
            _endsWithNewline = true;
        }

/// <summary>
        ///     Write formatted text directly into the generated output
        /// </summary>
        public void Write(string format, params object[] args)
        {
            Write(string.Format(CultureInfo.CurrentCulture, format, args));
        }

/// <summary>
        ///     Write formatted text directly into the generated output
        /// </summary>
        public void WriteLine(string format, params object[] args)
        {
            WriteLine(string.Format(CultureInfo.CurrentCulture, format, args));
        }

/// <summary>
        ///     Increase the indent
        /// </summary>
        public void PushIndent(string indent)
        {
            if ((indent == null))
            {
                throw new ArgumentNullException(nameof(indent));
            }
            CurrentIndent = (CurrentIndent + indent);
            IndentLengths.Add(indent.Length);
        }

/// <summary>
        ///     Remove the last indent that was added with PushIndent
        /// </summary>
        public string PopIndent()
        {
            var returnValue = "";
            if ((IndentLengths.Count > 0))
            {
                var indentLength = IndentLengths[(IndentLengths.Count - 1)];
                IndentLengths.RemoveAt((IndentLengths.Count - 1));
                if ((indentLength > 0))
                {
                    returnValue = CurrentIndent.Substring((CurrentIndent.Length - indentLength));
                    CurrentIndent = CurrentIndent.Remove((CurrentIndent.Length - indentLength));
                }
            }
            return returnValue;
        }

/// <summary>
        ///     Remove any indentation
        /// </summary>
        public void ClearIndent()
        {
            IndentLengths.Clear();
            CurrentIndent = "";
        }

#endregion

#region ToString Helpers

/// <summary>
        ///     Utility class to produce culture-oriented representation of an object as a string.
        /// </summary>
        public class ToStringInstanceHelper
        {
            private IFormatProvider _formatProviderField = CultureInfo.InvariantCulture;

/// <summary>
            ///     Gets or sets format provider to be used by ToStringWithCulture method.
            /// </summary>
            public IFormatProvider FormatProvider
            {
                get { return _formatProviderField; }
                set
                {
                    if ((value != null))
                    {
                        _formatProviderField = value;
                    }
                }
            }

/// <summary>
            ///     This is called from the compile/run appdomain to convert objects within an expression block to a string
            /// </summary>
            public string ToStringWithCulture(object objectToConvert)
            {
                if ((objectToConvert == null))
                {
                    throw new ArgumentNullException(nameof(objectToConvert));
                }
                var t = objectToConvert.GetType();
                var method = t.GetMethod("ToString", new[]
                {
                    typeof (IFormatProvider)
                });
                //if ((method == null))
                //{
                return objectToConvert.ToString();
                //}
                //return ((string) (method.Invoke(objectToConvert, new object[]
                //{
                //    _formatProviderField
                //})));
            }
        }

/// <summary>
        ///     Helper to produce culture-oriented representation of an object as a string
        /// </summary>
        public ToStringInstanceHelper ToStringHelper { get; } = new ToStringInstanceHelper();

#endregion
    }

时间: 2024-10-12 09:42:53

在UWP中使用T4的注意事项的相关文章

UWP中新加的数据绑定方式x:Bind分析总结

UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也没遇到麻烦.直到在园子里看到了这篇文章: http://www.cnblogs.com/gaoshang212/p/4534138.html 原来UWP的绑定中新加了个x:Bind,从文章中可以看到x:Bind的效率是很高的.找到MSDN(数据绑定)看了一下(完整的学习目录可参见: http://w

ASP.NET MVC 中的 T4

每次使用“添加视图”或“添加控制器”功能时,您都在 ASP.NET MVC 项目中使用 T4 模板.这些模板位于 Common7\IDE\ItemTemplates\CSharp\Web\MVC 2\CodeTemplates 文件夹的 Visual Studio 安装中.另外还提供了模板的 Visual Basic 版本,但是我将其作为读者推断文件夹名称的一个练习. 这些模板本身足以说明 T4 的价值和功能.例如,以下是 CodeTemplates 的 AddView 子文件夹中 List.t

[UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Entity Framework Core(Entity Framework 7)下文将简称:EF 1.在UWP中使用EF需要更新Microsoft.NETCore.UniversalWindowsPlatform到大于“5.2.2”的版本. 2.直接在“程序包管理器控制台”输入命令来更新:Update-P

在 UWP 中实现 Expander 控件

WPF 中的 Expander 控件在 Windows 10 SDK 中并不提供,本文主要说明,如何在 UWP 中创建这样一个控件.其效果如下图: 首先,分析该控件需要的一些特性,它应该至少包括如下三个属性: Content: 最重要的属性,设置该属性,可以使 Expander 控件显示其内容: Header: 控件的 Header: IsExpand: 当前是否展开. 接下来是定义其 UI,在这里使用 Grid,添加两行,一行显示 Header,一行显示 Content,当 IsExpand

在ASP.NET MVC5 中使用 FormsAuthenticationTicket 的注意事项

在根目录 web.confgi文件中添加如下配置信息. <configuration> <system.web> <authentication mode="Forms"> <forms loginUrl="~/Account/LogOn" timeout="2880" /> </authentication> </system.web> </configuration

详解 UWP 中的两种 HttpClient API

摘要: 本文为个人博客备份文章,原文地址:http://validvoid.net/demystifying-httpclient-apis-in-the-uwp/ 本文编译自微软 Building Apps for Windows 博客,原文地址:Demystifying HttpClient APIs in the Universal Windows Platform.本文原文由 Windows 网络 API 组的 Program Manager Sidharth Nabar 撰写. UWP

DB2中使用游标的注意事项

1. commit和rollback操作会让游标close掉,除非open的时候使用hold方式打开和使用游标 2. close掉cursor之后不用free cursor,但是close allcator之后要记得free allocator DB2中使用游标的注意事项

【编程开发】C语言中随机数rand使用注意事项

[编程开发]C语言中随机数rand使用注意事项 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:随机数在编程开发中非常重要,以C语言中的rand函数为例,使用时需要注意随机数的随机体现在哪里,比如是程序在不同的时刻执行时,相同位置的随机数是否需要一样,还是要每次执行生成的随机数也要不一样,等等,这些都是需要加以关注的地方. 经测试,发现,在不使用srand这个随机数种子的情况下:每次运行生成的随机数都是一样的.有的时候是需要这样子的,当然可以直接使

UWP中实现自定义标题栏

UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http://www.atmarkit.co.jp/ait/articles/1510/14/news022.html 看了下本想着翻译过来分享,但有些地方说的不是特别明确,所以自己实现了下,结合自己的体会总结了这篇文章. 0x01 UWP中的标题栏 一个普通的UWP窗口如下图所示: 我们可以通过两种方式获