IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Silverlight Discussion :

Plusieurs ViewModel pour une View: Locator?


Sujet :

Silverlight

  1. #1
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Septembre 2007
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2007
    Messages : 173
    Par défaut Plusieurs ViewModel pour une View: Locator?
    Bonjour à tous,

    Je développe sur application Silverlight 4, dans lequel j'implemente le MVVM avec le toolkit de Laurent Bugnion.

    Ma problèmatique est la suivante:
    J'ai plusieurs ViewModel dont j'ai besion dans une seule est même View (vue). J'ai pu voir que cela était possible en utilisant un pattern Locator.
    Malheureusement, tous les exemples que j'ai pu voir sur les Locator utilisent un seul ViewModel et à partir du moment où j'essaie le binding avec plusieurs ViewModel, plus rien ne fonctionne.

    Voici un exemple simple de ce que cherche à faire.

    Les objets du model (Objet1 et Objet2):
    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
    namespace SilverlightTestLocator.Model
    {
        public class Objet1 : INotifyPropertyChanged
        {
            private string name;
     
            public string Name
            {
                get { return name; }
                set 
                { 
                    name = value; 
                    if(PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    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
    namespace SilverlightTestLocator.Model
    {
        public class Objet2 : INotifyPropertyChanged
        {
            private string name;
     
            public string Name
            {
                get { return name; }
                set
                {
                    name = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Name"));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    Les ViewModel (ViewModel1 et ViewModel2)
    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
    namespace SilverlightTestLocator.ViewModel
    {
        public class ViewModel1 : INotifyPropertyChanged
        {
            private Objet1 obj1 = new Objet1();
     
            public Objet1 Obj1
            {
                get 
                {
                    if (obj1 == null)
                    {
                        obj1 = new Objet1()
                        {
                            Name = "Mon objet 1"
                        };
                    }
                    return obj1; 
                }
                set 
                { 
                    obj1 = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Obj1"));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    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
    namespace SilverlightTestLocator.ViewModel
    {
        public class ViewModel2 : INotifyPropertyChanged
        {
            private Objet2 obj2 = new Objet2();
     
            public Objet2 Obj2
            {
                get
                {
                    if (obj2 == null)
                    {
                        obj2 = new Objet2()
                        {
                            Name = "Mon objet 2"
                        };
                    }
                    return obj2;
                }
                set
                {
                    obj2 = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Obj2"));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    Mon Locator
    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
    namespace SilverlightTestLocator.ViewModel
    {
        public class Locator : INotifyPropertyChanged
        {
            private ViewModel1 wm1;
     
            public ViewModel1 Wm1
            {
                get { return wm1; }
                set 
                { 
                    wm1 = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Wm1"));
                }
            }
            private ViewModel2 wm2;
     
            public ViewModel2 Wm2
            {
                get { return wm2; }
                set 
                {
                    wm2 = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("Wm2"));
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    Création de la ressource static Locator dans App.xaml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                 xmlns:viewModel="clr-namespace:SilverlightTestLocator.ViewModel"
                 x:Class="SilverlightTestLocator.App"
                 >
        <Application.Resources>
            <viewModel:Locator x:Key="LocatorVM"/>
        </Application.Resources>
    </Application>
    La View dans laquelle je souhaite faire le binding
    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
    <UserControl x:Class="SilverlightTestLocator.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:viewModel="clr-namespace:SilverlightTestLocator.ViewModel"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400"
        DataContext="{Binding Source={StaticResource LocatorVM} }">
     
     
        <Grid x:Name="LayoutRoot" Background="White">
            <StackPanel>
                <TextBlock Text="Objet1:" />
                <TextBox Text="{Binding Path=Vm1.Obj1.Name}" />
     
                <TextBlock Text="Objet2:" />
                <TextBox Text="{Binding Path=Wm2.Obj2.Name}" />
            </StackPanel>
        </Grid>
    </UserControl>
    Bien sure le binding ne fonctionne pas


    Merci par avance pour votre aide

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Essaie ceci:
    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
    namespace SilverlightTestLocator.ViewModel
    {
    	public class Locator
    	{
    		private ViewModel1 wm1;
     
    		public ViewModel1 Wm1
    		{
    			get
    			{
    				lock (wm1)
    				{
    					if (wm1 == null)
    						wm1 = new ViewModel1();
    					return wm1;
    				}
    			}
    		}
    		private ViewModel2 wm2;
     
    		public ViewModel2 Wm2
    		{
    			get
    			{
    				lock (wm2)
    				{
    					if (wm2 == null)
    						wm2 = new ViewModel2();
    					return wm2;
    				}
    			}
    		}
    	}
    }
    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
    <UserControl x:Class="SilverlightTestLocator.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:viewModel="clr-namespace:SilverlightTestLocator.ViewModel"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400">   
     
        <Grid x:Name="LayoutRoot" Background="White">
            <StackPanel>
                <Grid DataContext="{Binding Source={StaticResource LocatorVM}, Path=Wm1 }">
                    <!-- Le contexte est un ViewModel1 -->
                    <TextBlock Text="Objet1:" />
                    <TextBox Text="{Binding Path=Obj1.Name}" />
                </Grid>
                <Grid DataContext="{Binding Source={StaticResource LocatorVM}, Path=Wm2 }">            
                    <!-- Le contexte est un ViewModel2 -->
                    <TextBlock Text="Objet2:" />
                    <TextBox Text="{Binding Path=Obj2.Name}" />
                </Grid>
            </StackPanel>
        </Grid>
    </UserControl>
    A noter:
    -Mes singletons sont pas top
    -Tu peux enlever les new Objet1() et new Objet2() des champs private vu que tu geres ca dans le get (ou sinon le == null du get sera toujours faux).
    -C'est un sacré fouilli entre les WM et VM

  3. #3
    Membre confirmé
    Profil pro
    Développeur Web
    Inscrit en
    Septembre 2007
    Messages
    173
    Détails du profil
    Informations personnelles :
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Septembre 2007
    Messages : 173
    Par défaut
    Merci pour ta précieuse aide

    Citation Envoyé par Nathanael Marchand Voir le message
    -Tu peux enlever les new Objet1() et new Objet2() des champs private vu que tu geres ca dans le get (ou sinon le == null du get sera toujours faux).
    En effet, après relecture c'est une erreur de ma part (copier/coller en plus).

    Citation Envoyé par Nathanael Marchand Voir le message
    -C'est un sacré fouilli entre les WM et VM
    Tout à fait, faute de frappe...

    Sinon ça fonctionne nickel!!
    J'ai juste rajouté un test de nullité pour chaque ViewModel.

    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
     
            private ViewModel1 wm1;
     
            public ViewModel1 Wm1
            {
    			get
    			{
                    if (wm1 == null)
                    {
                        wm1 = new ViewModel1();
                    }
    				lock (wm1)
    				{
    					if (wm1 == null)
    						wm1 = new ViewModel1();
    					return wm1;
    				}
    			}
            }

    Merci encore

  4. #4
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Ben j'avais deja fait a l'interieur du lock!
    Car la c'est pas thread-safe!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 19/08/2006, 08h15
  2. plusieurs css pour une page
    Par difficiledetrouver1pseudo dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 20/02/2006, 21h30
  3. plusieurs formulaires pour une seule page ?
    Par lifecraft dans le forum ASP
    Réponses: 9
    Dernier message: 01/02/2006, 09h48
  4. [C#] Plusieurs LinkButton pour une seule fonction
    Par FunnyDjo dans le forum ASP.NET
    Réponses: 3
    Dernier message: 08/06/2005, 22h01
  5. Réponses: 2
    Dernier message: 05/07/2004, 17h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo