C#用DesignSurface實現一個簡單的窗體設計器-創新互聯

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

創新互聯專注于企業全網整合營銷推廣、網站重做改版、清澗網站定制設計、自適應品牌網站建設、成都h5網站建設購物商城網站建設、集團公司官網建設、外貿網站建設、高端網站制作、響應式網頁設計等建站業務,價格優惠性價比高,為清澗等各大城市提供網站開發制作服務。

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

 C#用DesignSurface實現一個簡單的窗體設計器

 C#用DesignSurface實現一個簡單的窗體設計器

 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實現一個簡單的窗體設計器

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

 C#用DesignSurface實現一個簡單的窗體設計器

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

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

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

 C#用DesignSurface實現一個簡單的窗體設計器

 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實現一個簡單的窗體設計器

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

 C#用DesignSurface實現一個簡單的窗體設計器

  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 窗體設計器生成的代碼"); 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                     //包含方法{};,會重復生成{};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實現一個簡單的窗體設計器

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

 C#用DesignSurface實現一個簡單的窗體設計器

 C#用DesignSurface實現一個簡單的窗體設計器

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

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

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

 C#用DesignSurface實現一個簡單的窗體設計器

 C#用DesignSurface實現一個簡單的窗體設計器

 C#用DesignSurface實現一個簡單的窗體設計器

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

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

文章題目:C#用DesignSurface實現一個簡單的窗體設計器-創新互聯
文章出自:http://m.kartarina.com/article12/dodegc.html

成都網站建設公司_創新互聯,為您提供企業網站制作虛擬主機軟件開發品牌網站制作網站維護移動網站建設

廣告

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

成都seo排名網站優化
主站蜘蛛池模板: 国产在线拍偷自揄拍无码| 精品国产性色无码AV网站| 亚洲午夜无码AV毛片久久| 久久久精品无码专区不卡| 国产在线拍揄自揄拍无码| 亚洲另类无码专区丝袜| 亚洲va中文字幕无码| 亚洲成A∨人片在线观看无码| 内射人妻无码色AV天堂| 亚洲色无码一区二区三区| 亚洲精品无码久久久久APP| 国产精品无码无需播放器| 久久久精品天堂无码中文字幕 | 亚洲日韩乱码中文无码蜜桃臀网站| 日韩精品无码中文字幕一区二区| 日韩精品无码久久一区二区三| 亚洲国产成人精品无码区在线网站| 蜜臀亚洲AV无码精品国产午夜. | 最新无码人妻在线不卡| 国产精品无码AV一区二区三区| 日韩A无码AV一区二区三区| 亚洲久热无码av中文字幕| 精品无码日韩一区二区三区不卡 | a级毛片免费全部播放无码| 性色av极品无码专区亚洲| 精品久久亚洲中文无码| 亚洲AV日韩AV永久无码免下载| 波多野42部无码喷潮在线| 免费A级毛片无码久久版| 色综合色国产热无码一| 国产精品无码一区二区三区在| 亚洲av无码一区二区三区人妖| 亚洲国产成人精品无码区在线秒播 | 亚洲一区无码精品色| 无码人妻av一区二区三区蜜臀| 亚洲AV无码一区二区三区网址 | 少妇爆乳无码专区| 亚洲AV永久无码天堂影院| 亚洲日韩精品无码AV海量| 亚洲熟妇无码八V在线播放| 亚洲欧洲AV无码专区|