由于最近需要写一些界面稍微好看点的Winform程序,如果用原生控件,,想要达到好看的程度,需要花费比较大的功夫,因为之前使用过CefSharp,因此发觉如果是使用CEF+Html的方式,界面可以相对容易做的精致一点(其实就是设计完之后,找个前端人员切切图),但是,使用CEF+Html有个弊端就是,正常的软件,Header跟Footer大体是通用的,包括一些通用的js/css的引用以及菜单栏等等,,如果直接用html,有个问题就在于,,每个界面都要复制一遍,如果万一发生修改,每个页面又要来一次,或许都这里有朋友会说:”那可以使用vue或者ng的模板啊”,,实际情况是,,会用的人不多,但是会用jq的人大把.

     由于服务器端有Razor模板,可以很方便的使用Layout以及各种自己封装的View,但实际情况下,如果单独把Razor拿出来,实际上是只有将模板string+model解析成新的string的功能而已,因此,想要独立的使用Razor就需要为独立的Razor引擎补充一些功能,

 

首先需要补充的就是Layout功能

 开始动工之前,我们先来了解一下一些功能对应到Razor中,是怎么个实现方式的:

 

1.先来看一段简单的cshtml文件以及生成后的类:

   _Layout.cshtml

   

  1. 1 <html>
  2. 2 <head>
  3. 3 <title></title>
  4. 4 </head>
  5. 5 <body>
  6. 6
  7. 7
  8. 8 @RenderBody()
  9. 9
  10. 10 @RenderSection("test",false)
  11. 11
  12. 12 </body>
  13. 13 </html>

View Code

   Index.cshtml

  1. 1 @{
  2. 2 Layout = "_Layout.cshtml";
  3. 3 }
  4. 4
  5. 5 <p>sdfsdfsdfs</p>
  6. 6
  7. 7
  8. 8 @section test{
  9. 9 <p>ddddddddd</p>
  10. 10 }

View Code

   Index.cshtml生成后的代码:

  1. 1 #pragma warning disable 1591
  2. 2 namespace TEst
  3. 3 {
  4. 4 #line hidden
  5. 5 using System;
  6. 6 using System.Threading.Tasks;
  7. 7 public class TextFile1 : WindowsFormsApp2.RazorViewBase<WindowsFormsApp2.Model>
  8. 8 {
  9. 9
  10. 10 #pragma warning disable 1998
  11. 11 public async override global::System.Threading.Tasks.Task ExecuteAsync()
  12. 12 {
  13. 13 WriteLiteral("\r\n\r\n");
  14. 14 WriteLiteral("\r\n");
  15. 15 #line 5 "TextFile1.cshtml"
  16. 16
  17. 17 Layout = "sdfsdfsdfsf";
  18. 18
  19. 19 #line default
  20. 20 #line hidden
  21. 21 WriteLiteral("\r\n<html>\r\n<head>\r\n <title></title>\r\n</head>\r\n<body>\r\n");
  22. 22 DefineSection("ui", async () =>
  23. 23 {
  24. 24 WriteLiteral("\r\n ");
  25. 25 #line 15 "TextFile1.cshtml"
  26. 26 Write(Model.A1);
  27. 27
  28. 28 #line default
  29. 29 #line hidden
  30. 30 WriteLiteral(";\r\n ");
  31. 31 #line 16 "TextFile1.cshtml"
  32. 32 Write(Model.A1?.StartsWith("sfdsfdf"));
  33. 33
  34. 34 #line default
  35. 35 #line hidden
  36. 36 WriteLiteral("\r\n <p></p>\r\n ");
  37. 37 }
  38. 38 );
  39. 39 WriteLiteral("</body>\r\n</html>");
  40. 40 }
  41. 41 #pragma warning restore 1998
  42. 42 }
  43. 43 }
  44. 44 #pragma warning restore 1591

View Code

 

1.关于基类,Razor引擎可以设置本次生成的类的基类,并且,要求基类中需要实现几个函数,已供生成的子类调用

2.@section : 如果使用section关键字,编译后,其实是调用基类的DefineSection(string name, Func<Task> act)函数,

   如:在Layout 中,使用 Html.RenderSesction 函数输出

    那么在引用该Layout的页面中,如Index.csthml中,使用

   

  1. 1 @section header{
  2. 2 sdfsdfsdfsdfs
  3. 3 //TODO:其他需要输出在头部的标签
  4. 4 }

 

     对应到实际生成的代码,其实是这样的

 

  1. 1 DefineSection("header", async () =>
  2. 2 {
  3. 3 WriteLiteral("\r\n ");
  4. 4 #line 15 "TextFile1.cshtml"
  5. 5 Write(Model.A1);
  6. 6
  7. 7 #line default
  8. 8 #line hidden
  9. 9 WriteLiteral(";\r\n ");
  10. 10 #line 16 "TextFile1.cshtml"
  11. 11 Write(Model.A1?.StartsWith("sfdsfdf"));
  12. 12
  13. 13 #line default
  14. 14 #line hidden
  15. 15 WriteLiteral("\r\n <p></p>\r\n ");
  16. 16 }
  17. 17 )

     由生成的代码可以看到 ,@section 段的使用,需要基类实现 DefineSection(string name, Func<Task> act) 函数,并且将传入的函数存起来,等待Html.RenderSesction 触发时调用

 

3.RenderBody,该函数其实是直接把Index.cshtml中,非@section的部分直接输出,由ExecuteAsync函数开始,所有的WriteLiteral的结果总和,因为@section部分已经是通过DefineSection定义了,所以直接输出其他结果并不会干扰到

 

4.WriteLiteral和Write: WriteLiteral 直接输原始数据,Write除非是输出HtmlString,否则需要转码

5.ExecuteAsync函数:Razor其实上是把cshtml转成对ExecuteAsync函数的内容

6.VS 的IDE支持,,由于.net core 3.0还未出正式版.所以创建的项目为.net 4.5的,而引用的又是asp.net core 的Razor,所以在IDE支持上会有一点点的小区别:

   因此为了省的IDE报太多的错误,需要在基类中,添加几个用于糊弄IDE的函数和属性:

   

  1. public HttpContextFake Context { set; get; } //返回自己模拟的一个HttpContext的类,
  2. protected virtual void DefineSection(string name, Action act) //函数签名略微不同
  3. public virtual void Execute() //IDE认的就是这个函数,不存在会报错,但没有实际用途
  4. [Browsable(false),Obsolete]
  5. public class HttpContextFake
  6. {
  7. public System.Web.HttpApplication ApplicationInstance { get; }
  8. }

 

顺带附上Razor+NaneUI的项目的地址: https://gitee.com/kugar/Kugar.UI.RazorUI

 

以上是Razor一些小的细节,,下篇文章就开始来说怎么创建一个支持Layout的独立Razor了

 

版权声明:本文为kugar原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/kugar/p/10527782.html