0

0

C#利用DesignSurface实现简单的窗体设计器的方法介绍(图文)

黄舟

黄舟

发布时间:2017-03-17 13:14:58

|

5187人浏览过

|

来源于php中文网

原创

这篇文章主要介绍了c#利用designsurface如何实现简单窗体设计器的相关资料,文中通过图文及示例代码介绍的很详细,对大家具有一定的参考价值,需要的朋友们下面来一起学习学习吧。

System.ComponentModel.Design.DesignSurface是为设计组件提供一个用户界面,通过它可以实现一个简单的窗体设计器。

在构建之前,我们需要引入System.Design.dll,否则会出现找不到DesignSurface的错误。

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);
 }

运行后出现简单的一个UI设计器

但是该设计器并不能实现控件拖放和UI设计器,以及控件的属性配置。

为了支持从源代码加载初始化窗体,需要对源码中的相关方法进行解析,这里我们 CodeDomDesignerLoader来实现定制化业务,CodeDomDesignerLoader是提供用于实现基于 CodeDOM 的设计器加载程序的基类。

继承它的类需要重写CodeCompileUnit Parse()方法,来实现加载窗体:

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 source = new List();
  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;

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

Matlab语言的特点 中文WORD版
Matlab语言的特点 中文WORD版

本文档主要讲述的是Matlab语言的特点;Matlab具有用法简单、灵活、程式结构性强、延展性好等优点,已经逐渐成为科技计算、视图交互系统和程序中的首选语言工具。特别是它在线性代数、数理统计、自动控制、数字信号处理、动态系统仿真等方面表现突出,已经成为科研工作人员和工程技术人员进行科学研究和生产实践的有利武器。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看

下载
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()
   .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;
 }

窗体的显示,需要逐句进行C#解析,特别是InitializeComponent()方法。

.CS Code其实最简单的就是读取源代码,然后返回就可以了。当设计器添加控件或者绑定事件时,可以通过文本操作进行代码完善。


 //直接返回代码,最简单
 public string GetTextCSCode()
 {
 Flush();
 return CSTextCode;
 }

CodeDomHostLoader类中有OnComponentRename,在设计器重命名组件时候响应,这里可以修复后台.cs中的控件引用

 

但此设计器还有很多不完善的地方,后期有时间再完善吧。

总结

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

91

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

27

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

11

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

5

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

5

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

55

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 8.3万人学习

C 教程
C 教程

共75课时 | 4.4万人学习

C++教程
C++教程

共115课时 | 15.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号