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

Windows Presentation Foundation Discussion :

[MVVM WPF.net3.5] Questions sur les views et les viewsModel


Sujet :

Windows Presentation Foundation

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut [MVVM WPF.net3.5] Questions sur les views et les viewsModel
    Bonjour à tous,

    J'aurai deux questions.

    J'utilise un service locator qui me permet d'avoir les bonne viewsModel en fonction des views à ce niveau, les databinding sur les propriétés fonctionne parfaitement.

    1ere problématique:

    Depuis la mainView à travers le mainViewsModel je souhaite récupérer mon objet "StackPanel" pour ensuite le manipuler.

    Le but c'est de pouvoir gérer dynamiquement les UIElement en les ajoutant au stackPanel (à partir de mon mainViewsModel).

    Par ailleurs, à choisir entre un conteneur (stackpanel / contentControl / canvas).

    Ma 2eme problématique est l'affichage dynamique et la possibilité de les positionnés dans le conteneur.

    En utilisation concrète de l'application quelle conteneur serait le plus adapté ?

    ScreenShots en ci-joint.

    war120
    --
    Merci pour votre aide.
    Images attachées Images attachées    

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Le but c'est de pouvoir gérer dynamiquement les UIElement en les ajoutant au stackPanel (à partir de mon mainViewsModel).
    Si tu veux ajouter des éléments dynamiquement il ne faut pas utiliser une StackPanel mais une listbox (ou listview) dans le xaml et binder la propriété ItemsSource sur la liste des éléments du ViewModel

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Ma 2eme problématique est l'affichage dynamique et la possibilité de les positionnés dans le conteneur.

    En utilisation concrète de l'application quelle conteneur serait le plus adapté ?
    Ben ça dépend comment tu veux les afficher.
    Si tu veux simplement les aligner horizontalement ou verticalement un StackPanel peut faire l'affaire.
    Si tu veux définir les coordonnées X et Y toi même il faut un Canvas.

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    N'oublie pas qu'avec une ListBox (ou listView etc ..) tu peux spécifier le conteneur (StackPanel, Canvas ...) utilisé lors de l'affichage.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    Merci matdur,

    Je vais essayer ta solution avec la listbox.

    Donc pour les items ajoutés dans la listebox (UI element), en fonction des besoins, je pourrai récupérer mon item et de là, le manipuler dans le canvas.

    Si j'ai bien compris ?

    Problématique: Comment depuis la mainview (où j'instancierai ma canvas) manipuler l'objet Canvas dans ma mainViewModel pour modifié ses enfants, puisque je voudrai modifier mon canvas en fonction des notifications que je recevrai , elle étends de InotifyPropertyChanged.

    war120

  6. #6
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Il te suffit d'exposer une propriété, dans ton VM, qui sera une collection qui va être mise à jour en fonction de tes notifications. Ensuite, tu bindes cette collection à la propriété Children de ton Canvas/Grid/Panel/etc...

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Regarde le lien suivant, je pense qu'il répond à tes questions
    http://social.msdn.microsoft.com/For...7-71d20832e3ae

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    Merci pour vos réponses, je vais essayer sa.

  9. #9
    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
    Manipuler des éléments de la UI dans le VM c'est bof, ca sort du principe du mvvm

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    Que me conseillez-vous alors PitMaverick78 ?

  11. #11
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Citation Envoyé par war120 Voir le message
    Que me conseillez-vous alors PitMaverick78 ?
    Faire ce que j'ai dit: manipuler des collections qui seront bindées à l'IHM.

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    Bonsoir,

    J'ai essayer de binder une ObservableCollection de type UIElement sur la listebox, puis j'ai définis un conteneur de type Canvas en itemshost.

    Première impression :

    Je peux en effet, ajouter des vues dans la collection, mais aucunes vues n'est visible.

    MainView.xaml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    <ListBox ItemsSource="{Binding Path=Items}">
            <ListBox.Template>
                <ControlTemplate TargetType="{x:Type ListBox}">
                    <Canvas Name="myCanvas" IsItemsHost="True" />
                </ControlTemplate>
            </ListBox.Template>
        </ListBox>
    MainViewModel.cs

    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
     
            private ObservableCollection<UIElement> _items;
            public ObservableCollection<UIElement> Items
            {
                get
                {
                    return this._items;
                }
     
                set 
                {
                    this._items = new ObservableCollection<UIElement>();
                    this._items.Add(new LoginView());
                }
     
            }
    Le loginView est un UserControl.
    J'ai également essayé de récuperer l'élément (loginView) depuis ma collection pour modifier son attribut Visible, mais aucun affichage.

    Merci pour votre aide
    --
    war120

  13. #13
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    Il ne faut pas binder une collection de UIElement mais une collection d'objets métier. Ensuite, tu définis un DataTemplate qui sera appliqué sur ton ItemsControl. Sur cet objet métier, tu as 2 propriété, X et Y, qui te permettent de définir le Canvas.Top et Canvas.Let

  14. #14
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Par défaut
    Tout a fait d'accord avec avec Thomas un ViewModel ne devrait exposer que d'autres "ViewModel" ou alors des "Model" mais en aucun cas des éléments des l'interface graphique.

    Dans ton cas il faut que tu crées un ItemViewModel

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class ItemViewModel
    	{
    		public double X
    		{
    			get;
    			set;
    		}
     
    		public double Y
    		{
    			get;
    			set;
    		}
    	}
    et le ViewModel principale expose une collection de ItemViewModel

    public ObservableCollection<ItemViewModel> Items
    {
    get;
    set;

    }
    et la manière dont les items sont affichés est définie dans le xaml via un DataTemplate

  15. #15
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    Merci pour votre soutien.

    L'exemple de matdur:

    - la définition de deux variables X et Y pour le positionnement.

    J'ai ajouté une propriété Element de type UserControl :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pubic UserControl Element { get; set; }
    Pour tester, j'ai donc initialisé l'observableCollection puis insérer un nouveau itemViewModel dans mon mainViewModel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    this._items = new ObservableCollection<ItemViewModel>();
    this._items.Add(new ItemViewModel { X = 80, Y=10, Element= new LoginView()});
    Modification du mainview.xaml :

    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
     
        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas IsItemsHost="True" Width="auto" Height="auto"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <UserControl />  //récupération de la propriété Element 
                </DataTemplate>
            </ItemsControl.ItemTemplate>
            <ItemsControl.ItemContainerStyle>
                <Style>
                    <Setter Property="Canvas.Left" Value="{Binding X}" />
                    <Setter Property="Canvas.Top" Value="{Binding Y}" />
                </Style>
            </ItemsControl.ItemContainerStyle>
        </ItemsControl>
    Problématique:

    A ce niveau, je n'arrive pas à binder le UserControl (coté xaml) par rapport à celle que je définis dans la class ItemViewModel.

    J'ai essayé avec la propriété content, mais il s'affiche pas

    Merci pour votre aide
    --
    war120

  16. #16
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    t'as essayé un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <DataTemplate>
                    <UserControl Canvas.Left="{Binding X}" Canvas.Top="{Binding Y}" Content="{BindingElement" /> //récupération de la propriété Element 
                </DataTemplate>

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 7
    Par défaut
    oui, j'ai essayé mais aucun affichage.

  18. #18
    Rédacteur
    Avatar de Thomas Lebrun
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    9 161
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 9 161
    Par défaut
    _items, c'est bien une propriété ? Tu fais bien le raise du propertychange ?

Discussions similaires

  1. Questions sur la compatibilité et les version de VB
    Par jam92400 dans le forum Discussions diverses
    Réponses: 22
    Dernier message: 08/04/2008, 16h19
  2. 3 questions sur le web et les technologies associées
    Par amazircool dans le forum Général Conception Web
    Réponses: 3
    Dernier message: 20/07/2007, 00h16
  3. Des questions sur le C et les jeux (et interfaces)
    Par straitch dans le forum Développement 2D, 3D et Jeux
    Réponses: 8
    Dernier message: 02/07/2007, 17h21

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