


Introduction to the method of using DesignSurface to implement a simple form designer in C# (picture and text)
This article mainly introduces C# related information on how to use DesignSurface to implement a simple form designer. The article introduces it in detail through pictures, texts and sample codes. It has certain reference value for everyone. It needs Friends, come and study together.
System.ComponentModel.Design.DesignSurface
provides a user interface for the design component, through which a simple form designer can be implemented.
Before building, we need to introduce System.Design.dll
, otherwise there will be an error that the DesignSurface cannot be found.
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); }
After running, a simple UI designer appears
But the designer cannot implement drag-and-drop of controls and UI designer, as well as property configuration of controls.
In order to support loading the initialization form from the source code, the relevant methods in the source code need to be parsed. Here we use CodeDomDesignerLoader to implement customized services. CodeDomDesignerLoader provides the basis for implementing the designer loader based on CodeDOM. kind.
Inherit Its class needs to override the CodeCompileUnit Parse()
method to load the form:
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;
The parsing method is as follows, but This parsing is only used for code generation and cannot be used to display the user UI interface: the display of the
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("///".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; }
form requires C# parsing sentence by sentence, especially the InitializeComponent()
method.
. CS Code is actually the simplest thing to do is to read the source code and then return it. When the designer adds controls or binds events, you can complete the code through text operations.
//直接返回代码,最简单 public string GetTextCSCode() { Flush(); return CSTextCode; }
There is OnComponentRename in the CodeDomHostLoader class, which responds when the designer renames the component. Here you can repair the control reference in the background.cs
But there are still many imperfections in this designer. We will improve it later when we have time.
Summarize
The above is the detailed content of Introduction to the method of using DesignSurface to implement a simple form designer in C# (picture and text). For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics











Guide to Active Directory with C#. Here we discuss the introduction and how Active Directory works in C# along with the syntax and example.

Guide to C# Serialization. Here we discuss the introduction, steps of C# serialization object, working, and example respectively.

Guide to Random Number Generator in C#. Here we discuss how Random Number Generator work, concept of pseudo-random and secure numbers.

Guide to C# Data Grid View. Here we discuss the examples of how a data grid view can be loaded and exported from the SQL database or an excel file.

Guide to Factorial in C#. Here we discuss the introduction to factorial in c# along with different examples and code implementation.

The difference between multithreading and asynchronous is that multithreading executes multiple threads at the same time, while asynchronously performs operations without blocking the current thread. Multithreading is used for compute-intensive tasks, while asynchronously is used for user interaction. The advantage of multi-threading is to improve computing performance, while the advantage of asynchronous is to not block UI threads. Choosing multithreading or asynchronous depends on the nature of the task: Computation-intensive tasks use multithreading, tasks that interact with external resources and need to keep UI responsiveness use asynchronous.

Guide to Patterns in C#. Here we discuss the introduction and top 3 types of Patterns in C# along with its examples and code implementation.

Guide to Prime Numbers in C#. Here we discuss the introduction and examples of prime numbers in c# along with code implementation.
