2016-08-03 24 views
2

DER HINTERGRUNDC# Benutzerkontrolle Entwurfszeit Serialisierung

Ich arbeite an benutzerdefinierten WinForms Kontrolle. Steuerelement enthält DataGridView-Steuerelement, das mit einer der öffentlichen Eigenschaften verfügbar gemacht wird.

Ich habe benutzerdefinierte DesignerActionList und ControlDesigner implementiert, um visuelle Schnittstelle für DataGridView Spalten Manipulation (Hinzufügen, Entfernen, Ändern von Eigenschaften Werte) zu haben. Das funktioniert einwandfrei: Wenn ich mein Steuerelement einem neuen Formular hinzufüge, können Spalten hinzugefügt und zur Entwurfszeit angezeigt werden. sceenshot

Im Moment über die mir Fähigkeit zu implementieren Spalten Zustand {Steuerung} .Designer.cs

Ich habe implementiert individuellen Deisger Serializer wie unten zu speichern:

public class GridDesignerSerializer : CodeDomSerializer 
    { 
     public override object Serialize(IDesignerSerializationManager manager, object value) 
     { 
      var baseSerializer = (CodeDomSerializer)manager.GetSerializer(
        typeof(Grid).BaseType, 
        typeof(CodeDomSerializer)); 

      object codeObject = baseSerializer.Serialize(manager, value); 

      // now add some custom code 

      if (codeObject is CodeStatementCollection) 
      { 
       // add a custom comment to the code. 

       var statements = (CodeStatementCollection)codeObject; 
       statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code BEGIN:")); 

       // HERE COMPONENT INITIALIZATION INVOKES WILL BE PLACED. 

        statements.Add(new CodeCommentStatement("This is GridDesignerSerializer generated code :END")); 
      } 

      return codeObject; 
     } 
    } 

Und zusätzliche Steuerklasse Serialisierung Attribut:

[Designer(typeof(Grid_Designer))] 
[DesignerSerializer(typeof(GridDesignerSerializer), typeof(CodeDomSerializer))] 
public partial class Grid : UserControl 
{ ... 

DAS PROBLEM

Wenn ich eine neue Spalte in mein benutzerdefiniertes Steuerelement DataGridView zur Entwurfszeit eingefügt, werden keine Änderungen vom Designer erkannt (vs Dokument Registerkarte hat keine *). Wenn ich die Entwurfsansicht schließe, findet keine Serialisierung statt.

Wenn ich eine der anderen Steuerelementeigenschaften ändern (sagen wir: Ändern der Rahmenart), werden Änderungen erkannt und die benutzerdefinierte Serialisierung ausgeführt (zusätzlicher Kommentar zeigt den Inside Designer an).

DIE FRAGE

  1. Wie Desiger benachrichtigen, dass dort, wo aus (Spalten, in denen hinzugefügt) ändert, und Serialisierung durchführen?

  2. Inside GridDesignerSerializer Wie kann man die Entwurfszeit bestimmen DataGridView-Instanz, um über hinzugefügte Spalten zu iterieren, um Codegenerierung durchzuführen?

Vielen Dank für Anregungen.

+0

[IComponentChangeService] (https://msdn.microsoft.com/en-us/library/system.componentmodel.design.icomponentchangeservice (v = vs.110) .aspx) –

+0

Was ist der Grund für die Erstellung eines 'CodeDomSerializer'? –

+0

Grund: Generieren Sie Code innerhalb {Control} .Designer.cs für Spalten, die zu Entwurfszeit zu DataTreeView hinzugefügt werden. Etwas wie: {Control} .DataGridView.Columns.Add (...); –

Antwort

1

OK, ich glaube, Punkt 1 mit unten gelöst:

ich in meiner Kontrolle Klasse hinzugefügt haben:

private IComponentChangeService GetChangeService() 
    { 
     return (IComponentChangeService)GetService(typeof(IComponentChangeService)); 
    } 

Und dann innerhalb Methode/Eigenschaft, die für die Änderungserkennung verantwortlich ist:

this.GetChangeService().OnComponentChanged(this, null, null, null); 

Als Ergebnis, wenn ich eine Spalte in Datagridview hinzuzufügen, die * zeigt auf Dokument Registerkarte und benutzerdefinierte Serialisierung nach dem Speichern ist p erfuhr.

Punkt 2 auch: In meinem Fall fügen unten Code innerhalb GridDesignerSerializer:

var grid = ((Grid) value); statements.Add (neues CodeCommentStatement ("Spaltenanzahl:" + grid.List.Columns.Count.ToString()));

allgemeine Instanz von serialisierten Objekt zweites Argument von Serialize Methode:

Serialize(IDesignerSerializationManager manager, object value)