最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#利用DesignSurface如何實現(xiàn)簡單的窗體設計器

 更新時間:2017年02月25日 16:09:06   作者:JackWang-CUMT  
這篇文章主要介紹了C#利用DesignSurface如何實現(xiàn)簡單窗體設計器的相關資料,文中通過圖文及示例代碼介紹的很詳細,對大家具有一定的參考價值,需要的朋友們下面來一起學習學習吧。

System.ComponentModel.Design.DesignSurface是為設計組件提供一個用戶界面,通過它可以實現(xiàn)一個簡單的窗體設計器。

在構建之前,我們需要引入System.Design.dll,否則會出現(xiàn)找不到DesignSurface的錯誤。

private void Form1_Load(object sender, EventArgs e)
 {
  //引用System.Deisgn.dll
  DesignSurface ds = new DesignSurface();
  //開始加載窗體
  ds.BeginLoad(typeof(Form));
  Control designerContorl = (Control)ds.View;
  designerContorl.Dock = DockStyle.Fill;
  this.Controls.Add(designerContorl);
 }

運行后出現(xiàn)簡單的一個UI設計器

但是該設計器并不能實現(xiàn)控件拖放和UI設計器,以及控件的屬性配置。

為了支持從源代碼加載初始化窗體,需要對源碼中的相關方法進行解析,這里我們 CodeDomDesignerLoader來實現(xiàn)定制化業(yè)務,CodeDomDesignerLoader是提供用于實現(xiàn)基于 CodeDOM 的設計器加載程序的基類。

繼承它的類需要重寫CodeCompileUnit Parse()方法,來實現(xiàn)加載窗體:

protected override CodeCompileUnit Parse()
 {
  
  #region 源文件讀取
  var sw = new StreamReader(@"E:\FrmUser.cs");
  var sw_designer = new StreamReader(@"E:\FrmUser.Designer.cs");

  string formCodeCS = sw.ReadToEnd();
  string formCodeDesigner = sw_designer.ReadToEnd();

  List<string> source = new List<string>();
  source.Add(formCodeCS);
  source.Add(formCodeDesigner);

  #endregion
  //Rolsyn解析C#
  var rootDesigner = Source2CodeDom.Parse(formCodeDesigner);
  codeDesingerCompileUnit = Source2CodeDom.GetDesignerCodeComplieUnit(rootDesigner);
  var rootCS = Source2CodeDom.Parse(formCodeCS);
  codeCSCompileUnit = Source2CodeDom.GetCodeComplieUnit(rootCS);
  //MergeFormSource
  string mergeS = Source2CodeDom.MergeFormSource(formCodeDesigner, formCodeCS);
  codeMergeCompileUnit = Source2CodeDom.GetMergeDesignerCodeComplieUnit(mergeS);
  return codeMergeCompileUnit;

解析的方法如下,但是此解析只是用于代碼的生成,并不能用戶UI界面的顯示:

public static CodeCompileUnit GetDesignerCodeComplieUnit2(CompilationUnitSyntax root)
 {
  CodeCompileUnit ccu = new CodeCompileUnit();
  var firstMember = root.Members[0];
  var namespaceDeclration = (NamespaceDeclarationSyntax)firstMember;
  var designClassDeclaration = (ClassDeclarationSyntax)namespaceDeclration.Members[0];
  var myDesignerClass = new CodeTypeDeclaration(designClassDeclaration.Identifier.ToString());
  var initializeComponent = new CodeMemberMethod();
  var ns = new CodeNamespace(namespaceDeclration.Name.ToString());

  foreach (var m in designClassDeclaration.Members)
  {

  if (m is ConstructorDeclarationSyntax)
  {
   var ctor = ((ConstructorDeclarationSyntax)m);
   var codeBody = ctor.Body.ToString();
   codeBody = codeBody.Trim().TrimStart('{').TrimEnd('}').Trim().TrimEnd(';');
   CodeSnippetExpression csbody = new CodeSnippetExpression(codeBody);
   CodeExpressionStatement stmt = new CodeExpressionStatement(csbody);
   //Add the expression statements to the method.
   // InitializeComponent
   var cctor = new CodeConstructor();
   cctor.Name = ctor.Identifier.ToString();
   //var cmm = new CodeMemberMethod();
   //cmm.Name = ctor.Identifier.ToString();
   //cmm.Attributes = GetCtoRAttrMapping(ctor);
   //cmm.ReturnType = new CodeTypeReference(typeof(void));
   cctor.Statements.Add(stmt);

   myDesignerClass.Members.Add(cctor);
  }
  if (m is FieldDeclarationSyntax)
  {
   var F = ((FieldDeclarationSyntax)m);
   var type = F.Declaration.Type;
   foreach (var variable in F.Declaration.Variables)
   {
   var field = new CodeMemberField();
   field.Name = variable.Identifier.ToString();
   field.Type = new CodeTypeReference(type.ToString());
   field.Attributes = GetFieldAttrMapping(F);
   //field.InitExpression = new CodePrimitiveExpression(null);
   myDesignerClass.Members.Add(field);
   }
  }
  if (m is MethodDeclarationSyntax)
  {
   var node = m as MethodDeclarationSyntax;
   #region xml comments
   var xmlTrivia = node.GetLeadingTrivia()
   .Select(i => i.GetStructure())
   .OfType<DocumentationCommentTriviaSyntax>()
   .FirstOrDefault();

 

   #endregion



   var method = (MethodDeclarationSyntax)m;

   var cmm = new CodeMemberMethod();
   cmm.Name = method.Identifier.ToString();



   ///XML注釋
   string[] comments = xmlTrivia.ToString().Split("\r\n".ToCharArray());
   foreach (string text in comments)
   {
   if (text.Trim() != "")
   {
    cmm.Comments.Add(new CodeCommentStatement(text.Trim().TrimStart("http:///".ToCharArray()).Trim(), true));
   }
   }



   if (cmm.Name == "InitializeComponent")
   {
   //region 
   CodeRegionDirective codeRegion = new CodeRegionDirective(CodeRegionMode.Start, "Windows 窗體設計器生成的代碼");
   CodeRegionDirective codeEndRegion = new CodeRegionDirective(CodeRegionMode.End, "");

   cmm.StartDirectives.Add(codeRegion);
   cmm.EndDirectives.Add(codeEndRegion);
   }

   //MemberAttributes.Family is protected
   //cmm.Attributes = MemberAttributes.Override | MemberAttributes.Family;
   cmm.Attributes = GetMethodAttrMapping(method);
   cmm.ReturnType = new CodeTypeReference(method.ReturnType.ToString());

   foreach (var p in method.ParameterList.Parameters)
   {
   CodeParameterDeclarationExpression cpd = new CodeParameterDeclarationExpression();
   cpd.Name = p.Identifier.ToString();

   cpd.Type = new CodeTypeReference(p.Type.ToString());

   cmm.Parameters.Add(cpd);
   }
   //包含方法{};,會重復生成{};
   string codeBody = method.Body.ToString();
   codeBody = codeBody.Trim().TrimStart('{').TrimEnd('}').Trim().TrimEnd(';');
   if (codeBody != "")
   {
   CodeSnippetExpression csbody = new CodeSnippetExpression(codeBody);
   CodeExpressionStatement stmt = new CodeExpressionStatement(csbody);
   //Add the expression statements to the method.
   cmm.Statements.Add(stmt);
   }
   myDesignerClass.Members.Add(cmm);

  }
  if (m is MemberDeclarationSyntax)
  {

  }
  }

  ccu.Namespaces.Add(ns);

  //Partial Class
  myDesignerClass.IsPartial = true;
 

  ns.Types.Add(myDesignerClass);

  

  return ccu;
 }

窗體的顯示,需要逐句進行C#解析,特別是InitializeComponent()方法。

.CS Code其實最簡單的就是讀取源代碼,然后返回就可以了。當設計器添加控件或者綁定事件時,可以通過文本操作進行代碼完善。

 //直接返回代碼,最簡單
 public string GetTextCSCode()
 {
 Flush();
 return __CSTextCode;
 }

CodeDomHostLoader類中有OnComponentRename,在設計器重命名組件時候響應,這里可以修復后臺.cs中的控件引用

 

但此設計器還有很多不完善的地方,后期有時間再完善吧。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

相關文章

  • C#計算2個字符串的相似度

    C#計算2個字符串的相似度

    這篇文章主要為大家詳細介紹了C#計算2個字符串相似度的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • unity實現(xiàn)虛擬搖桿控制Virtual Joystick

    unity實現(xiàn)虛擬搖桿控制Virtual Joystick

    這篇文章主要為大家詳細介紹了unity實現(xiàn)虛擬搖桿控制Virtual Joystick,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • c#一個定時重啟的小程序實現(xiàn)代碼

    c#一個定時重啟的小程序實現(xiàn)代碼

    今天有個朋友找我問有沒有一些能像Windows一樣計劃任務重啟的軟件,我也不清楚。他它說能讓我做一個給他它么?我考慮了一下,他的服務器都是有安裝.NET框架的,那可以用.NET來使下~~!
    2008-09-09
  • C#實現(xiàn)將javascript文件編譯成dll文件的方法

    C#實現(xiàn)將javascript文件編譯成dll文件的方法

    這篇文章主要介紹了C#實現(xiàn)將javascript文件編譯成dll文件的方法,涉及C#編譯生成dll動態(tài)鏈接庫文件的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • C#常用自定義函數(shù)小結

    C#常用自定義函數(shù)小結

    這篇文章主要介紹了C#常用自定義函數(shù),包括將數(shù)組轉成字符串、DateTime時間格式轉換為Unix時間戳格式和生成某個范圍內的隨機數(shù),需要的朋友可以參考下
    2014-09-09
  • C# DES加密算法中向量的作用詳細解析

    C# DES加密算法中向量的作用詳細解析

    以下是對C#中DES加密算法中向量的作用進行了詳細的介紹,需要的朋友可以過來參考下
    2013-09-09
  • C#四種計時器Timer的區(qū)別和用法

    C#四種計時器Timer的區(qū)別和用法

    這篇文章介紹了C#四種計時器Timer的區(qū)別和用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#設計模式之外觀模式介紹

    C#設計模式之外觀模式介紹

    外觀模式:為子系統(tǒng)中的一組接口提供一個一致的界面,此模式定義了一個高層的接口,這個借口使得這子系統(tǒng)容易使用
    2012-10-10
  • c# 實現(xiàn)模糊PID控制算法

    c# 實現(xiàn)模糊PID控制算法

    這篇文章主要介紹了c# 實現(xiàn)模糊PID控制算法的示例代碼,幫助大家更好的理解和使用c#編程語言,感興趣的朋友可以了解下
    2020-12-12
  • C#交錯數(shù)組知識點分析

    C#交錯數(shù)組知識點分析

    在本篇文章里小編給大家整理的是關于C#交錯數(shù)組知識點分析,需要的朋友們參考下。
    2019-11-11

最新評論

邵武市| 富平县| 肇东市| 库尔勒市| 云龙县| 连平县| 沁水县| 新田县| 改则县| 南昌市| 万全县| 南靖县| 青冈县| 海城市| 红安县| 固阳县| 乌拉特中旗| 天镇县| 昌吉市| 乌拉特中旗| 临潭县| 泰和县| 湘乡市| 禄劝| 普定县| 东兰县| 安多县| 黔江区| 盱眙县| 涟水县| 云南省| 祁连县| 四子王旗| 获嘉县| 贺兰县| 卢氏县| 乐山市| 崇左市| 赤水市| 长沙市| 昭平县|