Pour des raisons de performance, les éventuels customizers ne sont pas instanciés à chaque fois qu'ils sont nécessaires (par exemple, à chaque ouverture de signalétique). Les customizers de signalétiques, par exemple, sont instanciés une seule fois, au démarrage de Mercator et stockés dans des propriétés statiques.
Cela implique qu'ils ont une durée de vie plus longue (le temps de la session Mercator) que les fenêtres sur lesquelles ils agissent (les fenêtres signalétiques). Ceci peut poser des problèmes au Garbage Collector (GC) de l'environnement .net (gestionnaire de mémoire inutilisée), si on a placé une liaison persistante entre le customizer et la fenêtre qu'il modifie.
Le cas le plus classique de liaison persistante est la souscription à un abonnement de la fenêtre par le customizer. Ceci empêchera toute récupération de l'espace mémoire occupé par la fenêtre, même lorsque celle-ci sera fermée par l'utilisateur. Dès lors, il est essentiel qu'un customizer se désabonne à tous les évènements auxquels il a souscrit. Alors que la sousciption à un évènement se fait à l'aide de +=, l'annulation de cette souscription se fait avec une syntaxe tout à fait identique, en remplaçant += par -=.
En général, la souscription aux évènements est faite via la méthode FormLoadCustomize de l'interface MercatorUi.ICustomizers.IFormLoadCustomizer.
De façon symétrique, l'annulation de la souscription se fera le plus souvent via la méthode FormClosedCustomize de l'interface MercatorUi.ICustomizers.IFormClosedCustomizer.
Lors de la programmation de customizers, il est essentiel de veiller scrupuleusement à l'application de ces principes. Si tel n'est pas le cas, Mercator consommera sans fin toujours davantage de mémoire.
Exemples : voir le code-source de :
Comme indiqué ci-dessus, un même customizer peut n'être instancié qu'une seule fois et être utilisé pour modifier plusieurs éléments de Mercator. Un customizer de signalétique sera donc créé de façon unique et utilisé pour chaque fenêtre de signalétique correspondant. Dès lors, il serait erroné de maintenir dans le customizer des propriétés privées qui seraient utilisées dans diverses méthodes de la classe.
Exemple de code-source erroné :
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using MercatorUi;
using MercatorApi;
namespace SigCli
{
public class Customizer : MercatorUi.ICustomizers. IFormLoadCustomizer , MercatorUi.ICustomizers. IFormClosedCustomizer
{
private MercatorUi.MovableControls. MovableTextBox textExp;
public void FormLoadCustomize( Form form)
{
MercatorUi.Forms.Sig. SigForm sigForm = (MercatorUi.Forms.Sig. SigForm )form;
textExp = (MercatorUi.MovableControls. MovableTextBox )sigForm.MovableControls[ "O37F122SIU" ];
textExp.ButtonCustom.Visible = true ;
textExp.ButtonCustomClick += new EventHandler (textExp_ButtonCustomClick);
}
public void FormClosedCustomize( Form form)
{
textExp.ButtonCustomClick -= new EventHandler (textExp_ButtonCustomClick);
}
void textExp_ButtonCustomClick( object sender, EventArgs e)
{
MercatorUi. Dialogs .Stop(textExp.Text);
}
}
}
Alors que sur le plan syntaxique, ce code est parfaitement compilable, il n'est pas logique. En effet, il ne fonctionnera que si on ouvre une seule fiche du signalétique correspondant à la fois. Si on ouvre une seconde fiche, le custormizer (qui est unique) stockera le pointeur vers le textbox de cette seconde fiche dans la propriété textExp. Si l'utilisateur revient dans la première fiche et clique sur le bouton du textbox, l'évènement textExp_ButtonCustomClick sera bien levé, mais textExp.Text correspondra à la valeur de la second fiche.
Exemple de code-source correct :
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using MercatorUi;
using MercatorApi;
namespace SigCli
{
public class Customizer : MercatorUi.ICustomizers. IFormLoadCustomizer , MercatorUi.ICustomizers. IFormClosedCustomizer
{
public void FormLoadCustomize( Form form)
{
MercatorUi.Forms.Sig. SigForm sigForm = (MercatorUi.Forms.Sig. SigForm )form;
MercatorUi.MovableControls. MovableTextBox textExp = (MercatorUi.MovableControls. MovableTextBox )sigForm.MovableControls[ "O37F122SIU" ];
textExp.ButtonCustom.Visible = true ;
textExp.ButtonCustomClick += new EventHandler (textExp_ButtonCustomClick);
}
public void FormClosedCustomize( Form form)
{
MercatorUi.Forms.Sig. SigForm sigForm = (MercatorUi.Forms.Sig. SigForm )form;
MercatorUi.MovableControls. MovableTextBox textExp = (MercatorUi.MovableControls. MovableTextBox )sigForm.MovableControls[ "O37F122SIU" ];
textExp.ButtonCustomClick -= new EventHandler (textExp_ButtonCustomClick);
}
void textExp_ButtonCustomClick( object sender, EventArgs e)
{
MercatorUi.MovableControls. MovableTextBox textBox = (MercatorUi.MovableControls. MovableTextBox )sender;
MercatorUi. Dialogs .Stop(textBox.Text);
}
}
}