Home Backend Development C#.Net Tutorial Introduction to the method of using DesignSurface to implement a simple form designer in C# (picture and text)

Introduction to the method of using DesignSurface to implement a simple form designer in C# (picture and text)

Mar 17, 2017 pm 01:14 PM

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);
 }
Copy after login

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;
Copy after login

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(&#39;{&#39;).TrimEnd(&#39;}&#39;).Trim().TrimEnd(&#39;;&#39;);
   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(&#39;{&#39;).TrimEnd(&#39;}&#39;).Trim().TrimEnd(&#39;;&#39;);
   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;
 }
Copy after login

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;
 }
Copy after login

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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

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

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1653
14
PHP Tutorial
1251
29
C# Tutorial
1224
24
Active Directory with C# Active Directory with C# Sep 03, 2024 pm 03:33 PM

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

C# Serialization C# Serialization Sep 03, 2024 pm 03:30 PM

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

Random Number Generator in C# Random Number Generator in C# Sep 03, 2024 pm 03:34 PM

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

C# Data Grid View C# Data Grid View Sep 03, 2024 pm 03:32 PM

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.

Factorial in C# Factorial in C# Sep 03, 2024 pm 03:34 PM

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 c# The difference between multithreading and asynchronous c# Apr 03, 2025 pm 02:57 PM

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.

Patterns in C# Patterns in C# Sep 03, 2024 pm 03:33 PM

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.

Prime Numbers in C# Prime Numbers in C# Sep 03, 2024 pm 03:35 PM

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

See all articles