国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#利用DesignSurface如何實現簡單的窗體設計器

2020-01-24 00:44:31
字體:
來源:轉載
供稿:網友

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

在構建之前,我們需要引入System.Design.dll,否則會出現找不到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); }

運行后出現簡單的一個UI設計器

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

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

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

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中的控件引用

 

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

總結

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 巢湖市| 收藏| 红安县| 浙江省| 伊川县| 随州市| 安仁县| 梁平县| 阜南县| 班玛县| 南乐县| 永登县| 神池县| 景宁| 湟源县| 泊头市| 勐海县| 镇江市| 静乐县| 西充县| 台南市| 隆安县| 瓦房店市| 宜都市| 肇州县| 乌兰县| 湖南省| 报价| 长宁区| 太湖县| 钟祥市| 花垣县| 米泉市| 察雅县| 绥江县| 廉江市| 南投市| 石台县| 会昌县| 八宿县| 元朗区|