Bonjour
Je farfouille pour trouver quelques bon exemple d'implémentation de Form Singleton
Suggestions ou lien sur le sujet sont bienvenus
Merci
Bonjour
Je farfouille pour trouver quelques bon exemple d'implémentation de Form Singleton
Suggestions ou lien sur le sujet sont bienvenus
Merci
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
C'est à dire ? tu veux implémenter le pattern singleton pour une Form ? En quoi est-ce différent des autres types ?
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Salut
A priori ce n'est pas particulierement différent mais une Form est quand meme une classe un peu particuliere ne fut-ce que par son interaction directe avec l'utilisateur (close etc)
Sincerement il m'est arrivé une seule fois en 2 ans de devoir réellement utiliser une classe singleton
Dans le cas present j'entrevois le besoin et l'intéret d'une Form singleton et je me demandais s'i y avais quelques remarques ou suggestions particulières !
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
A priori il n'y a pas de précautions particulières à prévoir par rapport à n'importe quel autre type...
Voilà une implémentation basique :
Code : 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 public class MyForm : Form { // Constructeur privé pour empêcher la création d'instances // à partir de l'extérieur de la classe private MyForm() { InitializeComponent(); } private static MyForm _instance; public static MyForm Instance { get { if (_instance == null) { _instance = new MyForm(); } return _instance; } } ... }
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Merci
En me basant sur d'autres exemple il y a aussi un intéret à la gestion eventuelle et interne du close pour rendre l'instance nulle
Code : 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 class ListSingletonForm : Form { protected ListSingletonForm() { } private static ListSingletonForm _instance = null; public static ListSingletonForm Instance { get { if (_instance == null) { _instance = new ListSingletonForm(); _instance.FormClosed += new FormClosedEventHandler(detruit); } return _instance; } } static void detruit(object sender, FormClosedEventArgs e) { _instance.FormClosed -= new FormClosedEventHandler(detruit); _instance = null; } }
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
Pourquoi pas... mais je me serais plutôt basé sur l'évènement Disposed
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
En fait, peu importe l'évènement qui se produit en premier, vu que les 2 se produiront de toutes façons. Par contre, sémantiquement, l'évènement Disposed convient mieux car c'est celui qui correspond à la destruction effective de la fenêtre. C'est à partir de cet évènement que la fenêtre ne sera vraiment plus utilisable.
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Ais-je loupé qq chose ?
J'esperais ne pas devoir m'abonner a l'event close lors de l'intanciation de la Form en espérant que le code ci apres allait remettre ma reference externe a null
Mais ce n'est pas le cas !!
Si j'ai bien capté je devrais tester non pas si ma reference externe est null mais si son contenu est null ... ?
En attendant j'e me suis AUSSI abonné a l'event extérieurement mais c'est moins joli
Code : 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 public static ListSingletonForm Instance { get { if (_instance == null) { _instance = new ListSingletonForm(); _instance.FormClosed += new FormClosedEventHandler(detruit); } return _instance; } set { return value; } } static void detruit(object sender, FormClosedEventArgs e) { _instance.FormClosed -= new FormClosedEventHandler(detruit); Instance = null; }
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
J'ai beau me tripatouiller les neurones, je vois pas comment ça pourrait être une bonne idée. Soit ta fenêtre a une durée de vie égale à ton appli, et alors t'as pas à te soucier de la disposer, puisque ton appli se ferme avec elle. Soit ta fenêtre peut s'ouvrir et se fermer plusieurs fois pendant la durée de vie de l'appli, et dans ce cas avoir une propriété "Instance" accessible de partout qui un coup renvoie une nouvelle fenêtre, un coup renvoie l'instance d'une fenêtre déjà affichée, voire en cours de Disposition me paraît un poilou dangereux.
J'ai déjà du mal avec le singleton, qui n'est qu'une variable globale déguisée. Mais une form singleton, ça me fait peur
Accesoirement, je comprends pas ce que tu veux dire :Qu'entends tu par contenu ?Si j'ai bien capté je devrais tester non pas si ma reference externe est null mais si son contenu est null ... ?
ಠ_ಠ
Salu Guuhl
Petit mot d'explication
C'est une app qui contient un MdiMain et plusieurs child presentant des documents differents
Selon le contenu du document on fait apparaitre une liste dans ma fenetre singleton, cette fenetre sera instanciée au niveau du MdiMain qui en sera le parent
Des lors chaque Child ayant un contenu adequat peut profiter de cette fenetre qui s'affiche en semi transparence
Cette fenetre n'est pas toujours necessaire
Le cas échéant Une seule sera necessaire
L'utilisateur peut la fermer ou la reouvrir a tout moment
J'ai voulu essayer un singleton et je n'en suis pas mécontent ..
Pour repondre a ta question
Tester si la reference elle meme est nulle ou si la reference referencie qq chose de nullQu'entends tu par contenu ?
(analogie au pointeurs en C)
Dans le cas present ma methode Detruit ne semble pas avoir d'effet externe car la reference externe reste desepèrément non nulle
Pour le coup je suis quand meme obligé de m'abonner a l'event FormClosed exterieurement
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 static void detruit(object sender, FormClosedEventArgs e) { _instance.FormClosed -= new FormClosedEventHandler(detruit); Instance = null; }
Code : 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 // *************************************************************************************** public FrmClusterListe frmClusterListe { get { if (this._frmClusterListe == null) { this._frmClusterListe = FrmClusterListe.Instance; this._frmClusterListe.FormClosed += new FormClosedEventHandler(remetANull); } return this._frmClusterListe; } set { this._frmClusterListe = value; } } // *************************************************************************************** private void remetANull(object sender, FormClosedEventArgs e) { this._frmClusterListe.FormClosed -= new FormClosedEventHandler(remetANull); this._frmClusterListe = null; } // ***************************************************************************************
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
Dans ce cas le plus simple serait de ne pas la fermer mais simplement de la cacher... (en gérant l'évènement FormClosing)
hein ?
j'ai encore moins compris
Ce que tu appelles la "référence externe", c'est la variable _frmClusterListe ?
C'est normal qu'elle ne soit pas mise à null... c'est une copie de la référence renvoyée par Instance, il n'y a aucune raison qu'elle soit mise à null quand tu mets Instance à null.
En fait j'ai l'impression que tu t'emmêles un peu les pinceaux sur les histoires de références... tu sembles croire que _frmClusterListe est une référence vers Instance, qui elle-même est une référence vers la Form. Mais un "référence vers une référence", ça n'existe pas en C#... _frmClusterListe et Instance sont tous les deux des références directes vers la Form.
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Salut TomLev
Oui !Ce que tu appelles la "référence externe", c'est la variable _frmClusterListe ?
C'est effectivement ce que j'ai comprisC'est normal qu'elle ne soit pas mise à null... c'est une copie de la référence renvoyée par Instance, il n'y a aucune raison qu'elle soit mise à null quand tu mets Instance à null.
C'est vrai mais le noeud est déméléEn fait j'ai l'impression que tu t'emmêles un peu les pinceaux sur les histoires de références... tu sembles croire que _frmClusterListe est une référence vers Instance, qui elle-même est une référence vers la Form.
Ca c'est pas vrai !Mais un "référence vers une référence", ça n'existe pas en C#...
Code : 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 List<int> lst=new List<int>(); m0(lst); // au retour count vaut 1 m1(ref lst); // au retour count vaut 0 private void m1(ref List<int> lst) { // tu passe une reference de reference lst.Add(5); lst = new List<int>(); } private void m0(List<int> lst) { // tu passe une reference lst.Add(5); lst = new List<int>(); }
La effectivement je comprends que si je met Instance a null je ne met pas la form a null et subsequement pas _frmClusterListe_frmClusterListe et Instance sont tous les deux des références directes vers la Form.
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
Pas de questions techniques par MP ! Le forum est là pour ça...
Tutoriels : Les nouveautés de C# 6 - Accès aux données avec Dapper - Extraction de données de pages web à l'aide de HTML Agility Pack - La sérialisation XML avec .NET (Aller plus loin) - Les markup extensions en WPF
Je pense que sur le fond on est d'accord mais j'insiste sur la particularité de mon exemple
Dans ce cas, on passe une variable par reference certe, mais cette variable est Déja une reférence sur la List<> donc, tu passe explicitement une reference sur une reference
Et la particularité a ne pas negliger c'est que si tu modifie le contenu de la liste dans la methode appeleé, ces modification se retrouveront dans la List comme si tu avait fait une appel normal (remontée implicite sur la cible source)
Mais si par contre tu reassigne une nouvelle Liste a la reference passée, c'est bien cette nouvelle Liste que tu va récupérer au retour de la methode, ce qui n'est pas le cas si tu avait passé sans le ref explicite
C'est effectivement un peu particulier mais bon a savoir !!
Et ce comportement n'est evidement pas le meme que si tu passe ta liste directement (reference implicite)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 List<int> lst = new List<int>(); m1(ref lst); // au retour count vaut 0 private void m1(ref List<int> lst) { // tu passe une reference de reference lst.Add(5); // si tu return ici la liste passée par la reference est bien modifiée lst = new List<int>(); // si tu return ici tu a perdu la liste passée en reference }
« Ils ne savaient pas que c'était impossible, alors ils l'ont fait ». (Twain)
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager