Bonjour !
J'ai créé un Designer en utilisant DesignSurface, IDesignerHost, etc...
Ça fonctionne plutôt bien, seulement j'ai un problème avec un contrôle qui n'est pas sérialisé correctement.
Admettons le contrôle suivant :
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 public class MonConteneur : UserControl { [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public Collection<UnAutreControl> Contient { get { return _Contient;} } // ... }
Comme vous le voyez, il contient une collection de contrôles et j'ai posé l'attribut pour indiquer au Designer qu'il faut sérialiser le contenu.
Seulement voilà, il ne sérialisait pas la propriété Contient.
J'ai donc créer un type "UnAutreControlCollection" qui hérite de Collection<UnAutreControl> pour pouvoir y ajouter mon propre sérialiseur :
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class UnAutreControlCollectionSerializer : CodeDomSerializer { public override object Serialize(IDesignerSerializationManager manager, object value) { UnAutreControlCollection hec = (UnAutreControlCollection)value; // La collection à sérialiser. ExpressionContext ec = (ExpressionContext)manager.Context.Current; // Le contexte actuel. // On créer une collection de Statement qui va contenir le résultat de la sérialisation (il n'y en aura qu'un). CodeStatementCollection Result = new CodeStatementCollection(); if(hec.Count == 0) return Result; // Déclare une variable locale. IComponent icmp = (IComponent)ec.Owner; CodeVariableDeclarationStatement cvds = new CodeVariableDeclarationStatement(typeof(UnAutreControl), String.Format("hle{0}{1}", icmp.Site.Name, i)); Result.Add(cvds); // Pour chaque élément dans la liste on créer un initialiseur. int i = 1; foreach(UnAutreControl hle in hec) { // Création d'une nouvelle instance. Result.Add( new CodeAssignStatement( new CodeVariableReferenceExpression(cvds.Name), new CodeObjectCreateExpression( typeof(UnAutreControl), new CodeExpression[]{}))); // Sérialise l'hyperlink. CodeVariableReferenceExpression cvre = new CodeVariableReferenceExpression(cvds.Name); ExpressionContext ecHle = new ExpressionContext(cvre, typeof(UnAutreControl), hec); manager.Context.Push(ecHle); CodeDomSerializer ItemSerializer = GetSerializer(manager, typeof(UnAutreControl)); CodeStatementCollection csc = ItemSerializer.Serialize(manager, hle) as CodeStatementCollection; object poped = manager.Context.Pop(); if (csc != null) Result.AddRange(csc); // Ajoute l'hyperlink à la collection Result.Add(new CodeMethodInvokeExpression(ec.Expression, "Add", new CodeExpression[]{ new CodeVariableReferenceExpression(cvds.Name) })); i++; } return Result; } }
Voilà, ca fonctionne plutôt bien dans le sens où :
- Ce sérialiseur est bien appelé par la sérialisation de Designer.
- Le code final obtenu contient bien la déclaration d'une variable, la création de l'instance de UnAutreControl, ainsi que l'ajout de cette instance dans la collection via la méthode Add de celle-ci.
Sauf que la sérialisation de l'instance de UnAutreControl ne retourne rien.
C'est à dire que la ligneretourne une collection vide alors qu'elle devrait retourner une collection contenant des CodeAssignStatement faisant l'affectation des propriétés du UnAutreControl.
Code : Sélectionner tout - Visualiser dans une fenêtre à part CodeStatementCollection csc = ItemSerializer.Serialize(manager, hle) as CodeStatementCollection;
Je m'y prend mal ? Une idée pour corriger le problème ?
Merci de votre aide.









Répondre avec citation
Partager