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

C# Discussion :

MVVM fenêtre unique


Sujet :

C#

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut MVVM fenêtre unique
    Bonjour,


    Je cherche à développer une application avec une seule fenêtre, mais dont le contenu va changer.
    Imaginons que j'ai une fenêtre avec plusieurs boutons qui vont avoir pour effet de changer entièrement le contenu de ma fenêtre pour par la suite revenir sur l'accueil via un bouton accueil disponible sur mes différentes vues.

    Je voudrais faire cela en respectant le MVVM au maximum.

    Je vous demande donc s'il existe un tuto ou quelqu'un qui sait comment faire, car je n'ai aucune idée de comment prendre la chose (voir même de la commencer).


    Merci d'avance pour votre aide.

  2. #2
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Le MVVM est utile à un autre niveau : entre chaque vue et ton modèle.
    Là tu as une problématique purement visuelle de navigation.

    Regarde du côté des API de navigation fournies par WPF : NavigationWindow et Page notamment.

    Si tu as seulement 2 vues c'est pê un peu overkill donc là tu peux te contenter d'un simple ContentControl qui contiendra la vue actuelle.
    Comme ça tu as en fait une seule vue "globale" qui gère notamment les menus.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  3. #3
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut
    Le problème est que si j'ai plus de fenêtre à créer, comment dois-je faire ?

    Mais je demande sa car je travail sur une application qui a plus de fenêtres et je n'arrive pas à saisir le fonctionnement de celle-ci.
    A l'heure actuelle elle change le view modèle courant mais je n'arrive pas à détecter ou se fait le changement de vue...

  4. #4
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Je ne sais pas comment est conçue cette application mais tu aurais typiquement :
    - une HomeView avec son HomeViewModel
    - une OtherView avec son OtherViewModel
    - une AnotherView avec son AnotherViewModel
    - une YetAnotherView avec son YetAnotherViewModel
    ...

    Tout ce qu'il y a à faire c'est changer le Content du ContentControl pour utiliser l'une de ces vues :
    - soit tu y vas à la bourrin en exposant globalement celui-ci, via la MainWindow typiquement, et tu le manipule directement depuis les gestionnaires de clic sur les boutons de navigation
    - soit tu utilises des évènements routés (voire des commandes) pour notifier de la demande de navigation et tu enregistres un handler au niveau de la MainWindow
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  5. #5
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut
    Est-il possible de binder le contentcontrol sur un ViewModel qui changerait et donc modifierai la fenêtre ?

    Car c'est ce qu'il semble être fait dans ce cas ?

    car j'ai trouvé ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     Content="{Binding PageCourante,
                                                  Mode=OneWay}"
                                ContentTemplate="{Binding PageCourante.Template,
                                                          Mode=OneWay}" />

    PageCourante serait donc un ViewModel qui retournerai sa View. (Template)

    Est-ce que je me trompe ?

  6. #6
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Oui tu peux faire ça mais pour moi c'est abuser du MVVM et risquer de complexifier.
    "Mon approche"© :
    - conserve l'état de navigation global dans une classe dédiée, e.g. Navigation, contenant un UserControl CurrentView
    - bind ton Content à cette CurrentView
    - change l'instance de CurrentView au gré de la navigation initiée par l'utilisateur.

    Dans le cas simple tu as une barre de navigation unique au niveau de la MainWindow qui te permet d'accéder aux différentes vues via autant de boutons (templatés comme il faut pour que ça ait un peu de gueule ).
    Sinon si tu as des patterns de navigation plus complexes avec possibilité de conserver un historique tu peux profiter des composants de navigation de WPF.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  7. #7
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut
    Oui, je suis plutôt d'accord avec toi.

    Car la je reprends le code d'une appli et je dois avouer que s'est pas évident.

    Mais il va falloir que je continue dans la même direction alors je prends mes marques comme je peux.


    De plus si tu as un exemple de ce dont tu parles pour que je puisse apprendre à maîtriser le sujet, je te serais très reconnaissant; je suis très intéressé dans apprendre plus.


    Merci beaucoup pour tes réponses.

  8. #8
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Voilà une petite illustration "quick and dirty" mais qui est une bonne base.

    Donc tu as des vues :
    1. Home :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      <UserControl x:Class="Navigation.HomeView"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
          <GroupBox Header="Home">
              <TextBlock>ET TELEPHONE MAISON</TextBlock>
          </GroupBox>
      </UserControl>
    2. Brandon :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      <UserControl x:Class="Navigation.BrandonView"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
          <GroupBox Header="Brandon">
              <TextBlock>MDR PTDR</TextBlock>
          </GroupBox>
      </UserControl>
    3. Jason :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      <UserControl x:Class="Navigation.JasonView"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                   mc:Ignorable="d" 
                   d:DesignHeight="300" d:DesignWidth="300">
          <GroupBox Header="Jason">
              <TextBlock>G PA COMPRITTE LA KESTION</TextBlock>
          </GroupBox>
      </UserControl>
    4. Kevin :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      <UserControl x:Class="Navigation.KevinView"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
          <GroupBox Header="Kevin">
              <TextBlock>KIKOO LOL</TextBlock>
          </GroupBox>
      </UserControl>


    Tu as une classe de navigation :
    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    public class Navigator : INotifyPropertyChanged
    {
        public static readonly Navigator Default = new Navigator();
     
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
     
        internal UserControl HomeView { get; set; }
        internal UserControl BrandonView { get; set; }
        internal UserControl JasonView { get; set; }
        internal UserControl KevinView { get; set; }
     
        private UserControl currentView;
        public UserControl CurrentView
        {
            get { return currentView; }
            set
            {
                if (value != currentView)
                {
                    currentView = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("CurrentView"));
                }
            }
        }
     
        internal void NavigateToHome()
        {
            CurrentView = HomeView;
        }
     
        internal void NavigateToBrandon()
        {
            CurrentView = BrandonView;
        }
     
        internal void NavigateToJason()
        {
            CurrentView = JasonView;
        }
     
        internal void NavigateToKevin()
        {
            CurrentView = KevinView;
        }
    }
    Une barre de navigation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <UserControl x:Class="Navigation.NavigationBar"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel Orientation="Horizontal">
            <Button Content="Home" Click="ButtonHome_Click"></Button>
            <Button Content="Kevin" Click="ButtonKevin_Click"></Button>
            <Button Content="Jason" Click="ButtonJason_Click"></Button>
            <Button Content="Brandon" Click="ButtonBrandon_Click"></Button>
        </StackPanel>
    </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
    using System.Windows;
    using System.Windows.Controls;
     
    namespace Navigation
    {
        /// <summary>
        /// Interaction logic for NavigationBar.xaml
        /// </summary>
        public partial class NavigationBar : UserControl
        {
            public NavigationBar()
            {
                InitializeComponent();
            }
     
            private void ButtonHome_Click(object sender, RoutedEventArgs e)
            {
                Navigator.Default.NavigateToHome();
            }
     
            private void ButtonKevin_Click(object sender, RoutedEventArgs e)
            {
                Navigator.Default.NavigateToKevin();
            }
     
            private void ButtonJason_Click(object sender, RoutedEventArgs e)
            {
                Navigator.Default.NavigateToJason();
            }
     
            private void ButtonBrandon_Click(object sender, RoutedEventArgs e)
            {
                Navigator.Default.NavigateToBrandon();
            }
        }
    }
    Et la fenêtre principale :
    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
    <Window x:Class="Navigation.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:Navigation"
            Title="MainWindow" Height="350" Width="525">
        <StackPanel>
            <Menu>
                <MenuItem Header="File">
                    <MenuItem Header="Exit" Click="MenuItem_Click"></MenuItem>
                </MenuItem>
            </Menu>
            <local:NavigationBar />
            <ContentControl Content="{Binding CurrentView,Source={x:Static local:Navigator.Default}}" />
        </StackPanel>
    </Window>
    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
    using System.Windows;
     
    namespace Navigation
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
     
                Navigator.Default.HomeView = new HomeView();
                Navigator.Default.BrandonView = new BrandonView();
                Navigator.Default.JasonView = new JasonView();
                Navigator.Default.KevinView = new KevinView();
     
                Navigator.Default.NavigateToHome();
            }
     
            private void MenuItem_Click(object sender, RoutedEventArgs e)
            {
                Application.Current.Shutdown();
            }
        }
    }
    Voilà, ni trivial ni compliqué.

    PS : dans les vues ce sont mes réflexions philosophiques les plus abouties.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  9. #9
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut
    Merci beaucoup pour cet exemple.

    J'essayerai de tester de trouver les diverses façon de réaliser ce système de fenêtre unique.


    ps : Si tu connais le nom des patterns que je peu trouver, je dit pas non.

  10. #10
    Membre expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 3 958
    Points
    3 958
    Par défaut
    Pas vraiment de nom de pattern pour ça, le mot clé c'est vraiment "navigation".
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  11. #11
    Membre régulier
    Homme Profil pro
    Ingénieur Junior développement logiciels
    Inscrit en
    Mai 2014
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Junior développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 198
    Points : 113
    Points
    113
    Par défaut
    ok, merci beaucoup pour ton aide .

    Il est difficile de passer après quelqu'un d'expérimenté quand on est jeune diplômé.

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

Discussions similaires

  1. [Python 3.X] Rendre une fenêtre unique
    Par Khar14 dans le forum Tkinter
    Réponses: 3
    Dernier message: 29/09/2014, 09h15
  2. [Lazarus] Fenêtre unique de développement
    Par rupteur dans le forum Lazarus
    Réponses: 2
    Dernier message: 08/09/2014, 11h47
  3. Fenêtre unique pour JDialog mais non modale
    Par Marc_3 dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 25/01/2013, 16h18
  4. Réponses: 6
    Dernier message: 09/08/2007, 21h41
  5. champ unique dans fenêtre indépendante
    Par burnout69 dans le forum Access
    Réponses: 12
    Dernier message: 07/09/2006, 21h37

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