bah si ca passe sans souci:
dans ce cas les deux instance fille passent bien par le singleton et appellent la meme instance du pere (en tout cas, l'instance est pas recreée)
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 public class mainViewModel : ViewModelBase{ private static mainViewModel instance; private static readonly object myLock = new object(); public mainViewModel() { getInstance(); } private mainViewModel(string arg) { } private static mainViewModel getInstance() { lock (myLock) { if (instance == null) instance = new mainViewModel("init"); return instance; } }
pfffff... merci a tous en tout cas... mais je comprend toujours pas...
Et celui la compte pour du beurre?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public mainViewModel() { getInstance(); }
Si tu veux reprendre les métaphores:
Toi tu es un humain, tu es aussi un mammifère. Humain hérite de mammifère, c'est à dire qu'un humain a les mêmes propriétés qu'un mammifère plus d'autre qui spécialisent le genre. Un humain n'a pas un petit mammifère caché à l'intérieur du ventre (enfin normalement).
Pareil pour une voiture, c'est un véhicule. Mais il n y a pas un véhicule caché dans la voiture.
L'héritage c'est "je suis" (ex. je suis un mammifère et un humain)
La composition "c'est je possède" (ex. je possède un cerveau).
Ce que tu veux faire toi ca n'est pas de l'héritage c'est de la composition.
il sert a apeller le singleton effectivement et c'est le seul moyen d'apeller le singleton
mais comment se fait il que j'ai deux passages par ce constructeur et que l'instance du mainviewmodel ne soit crée qu'une seule fois comme prévu du coup?
pcq, dans mes deux classes, j'ai ensuite deux objets différents
bon... je vais re re re regarder de mon coté
Merci... mais y a un truc qui coince... pour moi j'ai deux modèles distincts qui ont une partie commune (donc ils "sont" et pas ils possèdent)
ensuite, j'ai un singleton qui est utilisé et qui renvois mon instance, mais j'ai deux objets différents qui évoluent différemment a l'arrivée...
bref, j'ai toujours pas compris. Je vais re re re re re re re garder... vous prenez pas la tete, je reviendrais ensuite. Merci a tous
Mais parce que tu ne comprends pas l'héritage
Quand tu créés un objet F qui hérite d'une classe P, le constructeur de F appelle le constructeur de P. C'est pour ca que tu te retrouves avec 3 fois le constructeurs de P appelé: une fois par ton singleton bancal et deux fois par les constructeurs des classes qui héritent. Donc je le répète, si tu avais fait une implémentation correcte du singleton, non ca n'est pas un détail, tu aurais vite vu que ca n'était pas possible.
Je viens même de voir que tu construit 6 objets au lieu de trois avec le fait d'appeler ton getinstance dans le singleton (pour rappel un constructeur n'a pas de valeur de retour, il ne retourne donc pas la valeur retournée par getInstance).
Pour rappel un singleton (à peu près) correct:
TOUS les constructeurs doivent être PRIVATE. Le getter doit être PUBLIC (tu as fait exactement l'inverse)
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 class MaClasse { private static MaClasse _instance; private static readonly object Lock = new object(); public static MaClasse Instance { get { lock(Lock) { if(_instance == null) _instance = new MaClasse(); return _instance; } } } private MaClasse() { } }
Nan... éxécuté en pas a pas, je ne crée bien qu'une seule instance et le constructeur appelé 3 fois (puisque 3 modèles fils) ne créé qu'une seule fois le mainVm, ensuite l'instance du premier est bien passé en référence.
Je le re re re redis, les instances fonctionnent bien, il n'y a qu'une référence de mon VMpere, la même dans chaque VMfille...
au passage, il me semble qu'un constructeur renvois une valeur typée : celle de la classe en question...
j'ai un singleton sensiblement identique, c'est juste que le constructeur apelle et renvois le singleton.
C'est peut etre la ce qui cloche, mais je voulais ne pas avoir a faire de MaClasseFille.instance.MaPropriétéDuPere (mais directement MaClasseFille.MaPropriétéDuPere)
bref, je re re re re re re redis, les instances fonctionnent.
mais j'ai au niveau des appels "OnPropertyChanged" rien qui se passe
En fait en refaisant bien tout le déroulement, c'est au moment de la liaison au xaml que ca foire.
C'est les binding qui font comme si ils dupliquaient les objets
avant, mes VM semble bien pointer sur le même mainVM
J'ai en effet pu vérifier sur une valeur bindée qu'elle etait bien initialisée d'un coup dans tout les VMfilles.
Par contre au moment de la liaison (propriété bindée dans le xaml dans 2 usercontrol) dans le deuxième VMfille, la valeur est réévaluée, elle est considérée comme nulle dans la propriété alors que l'explorateur d'objet de visual studio lui donne bien une valeur
Bon écoute, je vais être franc, clair et bref:
Reprend à zéro la programmation objet car manifestement tu as trop de lacunes la dessus.
Tu ne peux pas considérer comme acquis, lorsque tu sors des énormités comme celles ci:
Tu ne maitrises ni la différence entre classe et objet, ni la notion d'héritage, ni les constructeurs.Nan... éxécuté en pas a pas, je ne crée bien qu'une seule instance et le constructeur appelé 3 fois (puisque 3 modèles fils) ne créé qu'une seule fois le mainVm, ensuite l'instance du premier est bien passé en référence.
Si tu passes trois fois dans un constructeur c'est que tu créées trois instances.
A ton avis combien tu créés d'objets la dedans? Ben tu en créés deux: une instance qui utilise le constructeur sans paramètres et une instance qui est créée avec le constructeur avec paramètre et qui est retourné par le getInstance, en plus ca n'est pas la valeur retournée par ton getInstance() qui est en "sortie" du constructeur. Bah oui une valeur on la retourne avec return or on ne peut pas mettre de return dans un constructeur. En effet dans un constructeur il retourne l'instance courante.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public mainViewModel() { getInstance(); }
Nathanael a raison, si tu passes 3 fois dans le constructeur c'est que tu as 3 instances differentes
1 appel au constructeur = 1 nouvelle instance : Et ça, tu peux pas faire autrement![]()
Ton singleton sert justement à ne PAS appeler le constructeur plus d'une fois.
oh bon ca va Nathanael... pas besoin d’être aussi condescendant!!
on part sur des gueguerres de termes, regarde mieux mon problème si tu en as envie... je sais bien qu'un constructeur crée une instance!
le but c'est que les trois instances apellée par l’héritage pointent sur une même instance du mainViewModel!
bref...
pour rester dans l'heritage (vu que je ne vois pas de solution simple via la composition perso...) il suffit de référencer les propriétés du MainViewModel sur celle du singleton
ca marche... jusqu'au moment ou je set une propriété dans un des UserControl, onPropertyChanged est bien levé, et le get de la propriété est bien appellé deux fois, mais l'affichage n'est pas mis a jour dans le second UserControl
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
28
29
30
31
32
33
34
35
36 public class mainViewModel : ViewModelBase { private static mainViewModel instance; private static readonly object myLock = new object(); public mainViewModel() { } private static mainViewModel Instance { get { if (instance == null) lock(myLock) instance = new mainViewModel(); return instance; } } #region currentUser private string _currentUser; public string currentUser { get { return Instance._currentUser; } set { Instance._currentUser = value; OnPropertyChanged("currentUser"); } } #endregion #region selectedApplication private string _selectedApplication; public string SelectedApplication { get { return Instance._selectedApplication; } set { Instance._selectedApplication = value; OnPropertyChanged("SelectedApplication"); initRolesList(); } }
[Edit Lordinaire] : yep, trois instances s'il faut, mais une seule contenant reellement mes données
alors je me répond une fois de plus...
la réponse était simple en fait:
ajouter "IsSynchronizedWithCurrentItem = true"
voila...
merci a tous!
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