>  기사  >  백엔드 개발  >  DesignSurface를 사용하여 C#으로 간단한 폼 디자이너를 구현하는 방법 소개(그림 및 텍스트)

DesignSurface를 사용하여 C#으로 간단한 폼 디자이너를 구현하는 방법 소개(그림 및 텍스트)

黄舟
黄舟원래의
2017-03-17 13:14:584846검색

이 글에서는 DesignSurface를 사용하여 간단한 폼 디자이너를 구현하는 방법에 대한 C# 관련 정보를 주로 소개합니다. 이 글에서는 이를 그림, 텍스트 및 샘플 코드를 통해 자세히 소개합니다. 친구가 필요합니다. 와서 함께 공부하세요.

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를 사용하여 맞춤형 서비스를 구현하는 기반을 제공합니다. 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<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;

구문 분석 방법은 다음과 같지만 이 구문 분석은 코드가 생성되었지만 사용자 UI 인터페이스를 표시할 수 없습니다.

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

양식을 표시하려면 문장별로 C# 구문 분석이 필요하며, 특히 InitializeComponent() 메서드가 필요합니다.

실제로 CS 코드는 소스 코드를 읽고 반환하는 것이 가장 간단합니다. 디자이너가 컨트롤을 추가하거나 이벤트를 바인딩하면 텍스트 작업을 통해 코드를 완성할 수 있습니다.


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

CodeDomHostLoader 클래스에는 디자이너가 구성 요소의 이름을 바꿀 때 응답하는 OnComponentRename이 있습니다. 여기에서 백그라운드 .cs

그런데 이 디자이너는 아직 부족한 부분이 많은데, 나중에 시간이 나면 개선해 나가겠습니다.

요약

위 내용은 DesignSurface를 사용하여 C#으로 간단한 폼 디자이너를 구현하는 방법 소개(그림 및 텍스트)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.