C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器-創(chuàng)新互聯(lián)

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

創(chuàng)新互聯(lián)專注于企業(yè)全網(wǎng)整合營銷推廣、網(wǎng)站重做改版、清澗網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、成都h5網(wǎng)站建設(shè)、購物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價格優(yōu)惠性價比高,為清澗等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

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

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

 1         protected override CodeCompileUnit Parse() 2         { 3           4             #region 源文件讀取 5             var sw = new StreamReader(@"E:\FrmUser.cs"); 6             var sw_designer = new StreamReader(@"E:\FrmUser.Designer.cs"); 7  8             string formCodeCS = sw.ReadToEnd(); 9             string formCodeDesigner = sw_designer.ReadToEnd();10 11             List<string> source = new List<string>();12             source.Add(formCodeCS);13             source.Add(formCodeDesigner);14 15             #endregion16             //Rolsyn解析C#17             var rootDesigner = Source2CodeDom.Parse(formCodeDesigner);18             codeDesingerCompileUnit = Source2CodeDom.GetDesignerCodeComplieUnit(rootDesigner);19             var rootCS = Source2CodeDom.Parse(formCodeCS);20             codeCSCompileUnit = Source2CodeDom.GetCodeComplieUnit(rootCS);21             //MergeFormSource22             string mergeS = Source2CodeDom.MergeFormSource(formCodeDesigner, formCodeCS);23             codeMergeCompileUnit = Source2CodeDom.GetMergeDesignerCodeComplieUnit(mergeS);24             return codeMergeCompileUnit;

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

  1        public static CodeCompileUnit GetDesignerCodeComplieUnit2(CompilationUnitSyntax root)  2         {  3             CodeCompileUnit ccu = new CodeCompileUnit();  4             var firstMember = root.Members[0];  5             var namespaceDeclration = (NamespaceDeclarationSyntax)firstMember;  6             var designClassDeclaration = (ClassDeclarationSyntax)namespaceDeclration.Members[0];  7             var myDesignerClass = new CodeTypeDeclaration(designClassDeclaration.Identifier.ToString());  8             var initializeComponent = new CodeMemberMethod();  9             var ns = new CodeNamespace(namespaceDeclration.Name.ToString()); 10  11             foreach (var m in designClassDeclaration.Members) 12             { 13  14                 if (m is ConstructorDeclarationSyntax) 15                 { 16                     var ctor = ((ConstructorDeclarationSyntax)m); 17                     var codeBody = ctor.Body.ToString(); 18                     codeBody = codeBody.Trim().TrimStart('{').TrimEnd('}').Trim().TrimEnd(';'); 19                     CodeSnippetExpression csbody = new CodeSnippetExpression(codeBody); 20                     CodeExpressionStatement stmt = new CodeExpressionStatement(csbody); 21                     //Add the expression statements to the method. 22                     // InitializeComponent 23                     var cctor = new CodeConstructor(); 24                     cctor.Name = ctor.Identifier.ToString(); 25                     //var cmm = new CodeMemberMethod(); 26                     //cmm.Name = ctor.Identifier.ToString(); 27                     //cmm.Attributes = GetCtoRAttrMapping(ctor); 28                     //cmm.ReturnType = new CodeTypeReference(typeof(void)); 29                     cctor.Statements.Add(stmt); 30  31                     myDesignerClass.Members.Add(cctor); 32                 } 33                 if (m is FieldDeclarationSyntax) 34                 { 35                     var F = ((FieldDeclarationSyntax)m); 36                     var type = F.Declaration.Type; 37                     foreach (var variable in F.Declaration.Variables) 38                     { 39                         var field = new CodeMemberField(); 40                         field.Name = variable.Identifier.ToString(); 41                         field.Type = new CodeTypeReference(type.ToString()); 42                         field.Attributes = GetFieldAttrMapping(F); 43                         //field.InitExpression = new CodePrimitiveExpression(null); 44                         myDesignerClass.Members.Add(field); 45                     } 46                 } 47                 if (m is MethodDeclarationSyntax) 48                 { 49                     var node = m as MethodDeclarationSyntax; 50                     #region xml comments 51                     var xmlTrivia = node.GetLeadingTrivia() 52                         .Select(i => i.GetStructure()) 53                         .OfType<DocumentationCommentTriviaSyntax>() 54                         .FirstOrDefault(); 55  56         57  58                     #endregion 59  60  61  62                     var method = (MethodDeclarationSyntax)m; 63  64                     var cmm = new CodeMemberMethod(); 65                     cmm.Name = method.Identifier.ToString(); 66  67  68  69                     ///XML注釋 70                     string[] comments = xmlTrivia.ToString().Split("\r\n".ToCharArray()); 71                     foreach (string text in comments) 72                     { 73                         if (text.Trim() != "") 74                         { 75                             cmm.Comments.Add(new CodeCommentStatement(text.Trim().TrimStart("http:///".ToCharArray()).Trim(), true)); 76                         } 77                     } 78  79  80  81                     if (cmm.Name == "InitializeComponent") 82                     { 83                         //region  84                         CodeRegionDirective codeRegion = new CodeRegionDirective(CodeRegionMode.Start, "Windows 窗體設(shè)計(jì)器生成的代碼"); 85                         CodeRegionDirective codeEndRegion = new CodeRegionDirective(CodeRegionMode.End, ""); 86  87                         cmm.StartDirectives.Add(codeRegion); 88                         cmm.EndDirectives.Add(codeEndRegion); 89                     } 90  91                     //MemberAttributes.Family is protected 92                     //cmm.Attributes = MemberAttributes.Override | MemberAttributes.Family; 93                     cmm.Attributes = GetMethodAttrMapping(method); 94                     cmm.ReturnType = new CodeTypeReference(method.ReturnType.ToString()); 95  96                     foreach (var p in method.ParameterList.Parameters) 97                     { 98                         CodeParameterDeclarationExpression cpd = new CodeParameterDeclarationExpression(); 99                         cpd.Name = p.Identifier.ToString();100 101                         cpd.Type = new CodeTypeReference(p.Type.ToString());102 103                         cmm.Parameters.Add(cpd);104                     }105                     //包含方法{};,會重復(fù)生成{};106                     string codeBody = method.Body.ToString();107                     codeBody = codeBody.Trim().TrimStart('{').TrimEnd('}').Trim().TrimEnd(';');108                     if (codeBody != "")109                     {110                         CodeSnippetExpression csbody = new CodeSnippetExpression(codeBody);111                         CodeExpressionStatement stmt = new CodeExpressionStatement(csbody);112                         //Add the expression statements to the method.113                         cmm.Statements.Add(stmt);114                     }115                     myDesignerClass.Members.Add(cmm);116 117                 }118                 if (m is MemberDeclarationSyntax)119                 {120 121                 }122             }123 124             ccu.Namespaces.Add(ns);125 126             //Partial Class127             myDesignerClass.IsPartial = true;128    129 130             ns.Types.Add(myDesignerClass);131 132           133 134             return ccu;135         }

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

1 //直接返回代碼,最簡單2  public string GetTextCSCode()3  {4        Flush();5        return __CSTextCode;6 }

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

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

 C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器

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

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

文章題目:C#用DesignSurface實(shí)現(xiàn)一個簡單的窗體設(shè)計(jì)器-創(chuàng)新互聯(lián)
文章出自:http://www.muchs.cn/article12/dodegc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、虛擬主機(jī)、軟件開發(fā)、品牌網(wǎng)站制作網(wǎng)站維護(hù)、移動網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化