Heim  >  Artikel  >  Backend-Entwicklung  >  Einführung in die Methode zur Verwendung von DesignSurface zur Implementierung eines einfachen Formulardesigners in C# (Bild und Text)

Einführung in die Methode zur Verwendung von DesignSurface zur Implementierung eines einfachen Formulardesigners in C# (Bild und Text)

黄舟
黄舟Original
2017-03-17 13:14:584844Durchsuche

In diesem Artikel werden hauptsächlich C#-bezogene Informationen zur Verwendung von DesignSurface zur Implementierung eines einfachen Formulardesigners vorgestellt. Der Artikel stellt ihn anhand von Bildern, Text und Beispielcode detailliert vor. Es braucht Freunde, die zusammenkommen und lernen.

System.ComponentModel.Design.DesignSurface stellt eine Benutzeroberfläche für die Designkomponente bereit, über die ein einfacher Formulardesigner implementiert werden kann.

Vor dem Erstellen müssen wir System.Design.dll einführen, andernfalls tritt die Fehlermeldung auf, dass DesignSurface nicht gefunden werden kann.

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

Ein einfacher UI-Designer erscheint nach dem Ausführen von

Aber der Designer kann keine Steuerelemente per Drag & Drop implementieren UI-Designer sowie Eigenschaftskonfiguration von Steuerelementen.

Um das Laden des Initialisierungsformulars aus dem Quellcode zu unterstützen, müssen die relevanten Methoden im Quellcode analysiert werden. Hier verwenden wir CodeDomDesignerLoader, um benutzerdefinierte Dienste zu implementieren auf CodeDOM Art.

Erbt und seine Klasse muss die Methode CodeCompileUnit Parse() überschreiben, um das Formular zu laden:

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;

Die Analysemethode ist wie folgt, aber diese Analyse ist Nur für Die Generierung von Code ermöglicht nicht die Anzeige der Benutzeroberfläche: Die Anzeige des

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

-Formulars erfordert eine satzweise C#-Analyse, insbesondere die InitializeComponent()-Methode.

Eigentlich ist es am einfachsten, den Quellcode zu lesen und ihn dann zurückzugeben. Wenn der Designer Steuerelemente hinzufügt oder Ereignisse bindet, können Sie den Code durch Textoperationen vervollständigen.


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

In der CodeDomHostLoader-Klasse gibt es OnComponentRename, das reagiert, wenn der Designer die Komponente umbenennt. Hier können Sie die Steuerreferenz im Hintergrund .cs

korrigieren

Aber es gibt noch viele Unvollkommenheiten in diesem Designer. Wir werden später Zeit haben, ihn zu verbessern.

Zusammenfassung

Das obige ist der detaillierte Inhalt vonEinführung in die Methode zur Verwendung von DesignSurface zur Implementierung eines einfachen Formulardesigners in C# (Bild und Text). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn