欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#利用DesignSurface如何實(shí)現(xiàn)簡(jiǎn)單的窗體設(shè)計(jì)器

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

System.ComponentModel.Design.DesignSurface是為設(shè)計(jì)組件提供一個(gè)用戶(hù)界面,通過(guò)它可以實(shí)現(xiàn)一個(gè)簡(jiǎn)單的窗體設(shè)計(jì)器。

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

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

運(yùn)行后出現(xiàn)簡(jiǎn)單的一個(gè)UI設(shè)計(jì)器

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

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

繼承它的類(lèi)需要重寫(xiě)CodeCompileUnit Parse()方法,來(lái)實(shí)現(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;

解析的方法如下,但是此解析只是用于代碼的生成,并不能用戶(hù)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 窗體設(shè)計(jì)器生成的代碼");
   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);
   }
   //包含方法{};,會(huì)重復(fù)生成{};
   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;
 }

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

.CS Code其實(shí)最簡(jiǎn)單的就是讀取源代碼,然后返回就可以了。當(dāng)設(shè)計(jì)器添加控件或者綁定事件時(shí),可以通過(guò)文本操作進(jìn)行代碼完善。

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

CodeDomHostLoader類(lèi)中有OnComponentRename,在設(shè)計(jì)器重命名組件時(shí)候響應(yīng),這里可以修復(fù)后臺(tái).cs中的控件引用

 

但此設(shè)計(jì)器還有很多不完善的地方,后期有時(shí)間再完善吧。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • Unity 實(shí)現(xiàn)貼花效果的制作教程

    Unity 實(shí)現(xiàn)貼花效果的制作教程

    有些游戲中的戰(zhàn)斗痕跡的效果會(huì)通過(guò)貼花來(lái)實(shí)現(xiàn)的,貼花的方式多種多樣。而在Unity中,有一種給官方文檔提供代碼的解決方案。本文將這些代碼的基礎(chǔ)上做一個(gè)繪圖的貼花效果,感興趣的童鞋可以參考一下
    2021-11-11
  • 利用C#實(shí)現(xiàn)最基本的小說(shuō)爬蟲(chóng)示例代碼

    利用C#實(shí)現(xiàn)最基本的小說(shuō)爬蟲(chóng)示例代碼

    最近在學(xué)習(xí)c#,碰巧遇到個(gè)小說(shuō)站不錯(cuò),就索性當(dāng)個(gè)練習(xí),所以這篇文章主要給大家介紹了關(guān)于利用C#實(shí)現(xiàn)最基本的小說(shuō)爬蟲(chóng)的相關(guān)資料,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-10-10
  • Winform窗體效果實(shí)例分析

    Winform窗體效果實(shí)例分析

    這篇文章主要介紹了Winform窗體效果,涉及WinForm窗體設(shè)計(jì)的常見(jiàn)參數(shù)設(shè)置及使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09
  • C#調(diào)用exe文件的方法詳解

    C#調(diào)用exe文件的方法詳解

    這篇文章主要為大家詳細(xì)介紹了C#調(diào)用exe文件的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-04-04
  • C#中IsNullOrEmpty和IsNullOrWhiteSpace的使用方法及區(qū)別解析

    C#中IsNullOrEmpty和IsNullOrWhiteSpace的使用方法及區(qū)別解析

    今天我們將探討C#中兩個(gè)常用的字符串處理方法:IsNullOrEmpty和IsNullOrWhiteSpace,本文中,我們將詳細(xì)解釋這兩個(gè)方法的功能和使用場(chǎng)景,并幫助您更好地理解它們之間的區(qū)別,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • 淺析C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式

    淺析C#數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式

    本篇文章是對(duì)C#中數(shù)據(jù)類(lèi)型轉(zhuǎn)換的幾種形式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-07-07
  • c#根據(jù)網(wǎng)址抓取網(wǎng)頁(yè)截屏生成圖片的示例

    c#根據(jù)網(wǎng)址抓取網(wǎng)頁(yè)截屏生成圖片的示例

    本文主要介紹了c#根據(jù)網(wǎng)址抓取網(wǎng)頁(yè)截屏生成圖片并保存的示例,代碼中使用了WebBrowser控件來(lái)完成這個(gè)功能,大家參考使用吧
    2014-01-01
  • 詳解WPF如何使用必應(yīng)地圖控件

    詳解WPF如何使用必應(yīng)地圖控件

    這篇文章主要為大家詳細(xì)介紹了WPF如何使用必應(yīng)地圖控件,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,感興趣的小伙伴可以了解一下
    2022-11-11
  • C#實(shí)現(xiàn)兩個(gè)日期比較大小

    C#實(shí)現(xiàn)兩個(gè)日期比較大小

    這篇文章主要為大家詳細(xì)介紹了C#中實(shí)現(xiàn)兩個(gè)日期比較大小的常見(jiàn)方法,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-12-12
  • C#采用OpenXml給Word文檔添加表格

    C#采用OpenXml給Word文檔添加表格

    這篇文章主要介紹了C#采用OpenXml給Word文檔添加表格的方法,是OpenXml操作Word的一個(gè)非常實(shí)用的技巧,需要的朋友可以參考下
    2014-09-09

最新評(píng)論