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 :

Une vue pour les contrôler tous


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mars 2012
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 19
    Par défaut Une vue pour les contrôler tous
    Bonjour,

    Sous ce titre quelque peu racoleur, j'ai 2 questions simples.
    Est il "conforme" d'avoir 1 seule vue pour plusieurs ViewModel et comment transmettre à cette vue les bonnes données selon le ViewModel utilisé?


    Car voici mon dilemme.
    Je dois afficher des coordonnées de nos clients (nom, prénom, adresse etc...) pour :
    -celui que l'on livre
    -celui qui nous paye

    Les champs à afficher sont identiques pour les 2, seules les données peuvent peuvent être différentes.
    Dans mon esprit, une unique vue est donc nécessaire.


    Je parviens parfaitement à afficher ma vue pour plusieurs ViewModel, mais je ne sais pas binder les données...



    Voici ce que j'ai fait (en simplifiant, j'espère que ça restera compréhensible).
    J'ai crée une fenêtre principale qui affichera 2 boutons (sous forme de listbox dynamique), "livré à" et "payeur" :

    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
    <UserControl x:Class="Discovery.View.BaseInfoView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:ViewModel="clr-namespace:ViewModel"
                 xmlns:View="clr-namespace:Discovery.View">
     
        <UserControl.Resources>
            <DataTemplate DataType="{x:Type ViewModel:ShipToViewModel}">
                <View:CustomerInfoView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModel:SoldToViewModel}">
                <View:CustomerInfoView />
            </DataTemplate>
        </UserControl.Resources>
     
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="40"/>
                <RowDefinition />
            </Grid.RowDefinitions>
     
            <ListBox Grid.Row="0" Name="LstCustomerInfo" ItemsSource="{Binding SubMenus}" SelectedIndex="0">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
     
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" Padding="10" VerticalAlignment="Center"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
     
            <GroupBox Grid.Row="1">
                <ContentControl Content="{Binding ElementName=LstCustomerInfo, Path=SelectedItem}"/>
            </GroupBox>
        </Grid>
    </UserControl>

    Fenêtre contrôlée par un 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
    20
    21
    22
    23
    24
    25
    26
    27
    namespace ViewModel
    {
        class BaseInfoViewModel : BaseViewModel
        {
            public override string Name 
            {
                get { return "Info de base"; } 
            }
     
     
            private readonly ObservableCollection<BaseViewModel> _submenus;
            public ObservableCollection<BaseViewModel> SubMenus
            {
                get { return this._submenus; }
            }
     
     
     
            public BaseInfoViewModel()
            {
                this._submenus = new ObservableCollection<BaseViewModel>();
     
                this._submenus.Add(new ShipToViewModel());
                this._submenus.Add(new SoldToViewModel());
            }
        }
    }

    Les 2 ViewModel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace ViewModel
    {
        public class ShipToViewModel : BaseViewModel
        {
            public override string Name
            {
                get { return "Livré à "; }
            }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace ViewModel
    {
        class SoldToViewModel : BaseViewModel
        {
            public override string Name
            {
                get { return "Payeur"; }
            }
        }
    }

    Et un UserControl devant afficher toutes les coordonnées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <UserControl x:Class="Discovery.View.CustomerInfoView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <Grid>
            <TextBlock Text="Nom : " />
            <TextBlock Text="{Binding Name1, Mode=OneWay}" />
        </Grid>
    </UserControl>

    Les Model utilisés sont ceux ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace Model
    {
        public class DiscoveryModel
        {
            public string ID { get; set; }
            public string Qualification { get; set; }
            public CustomerInfo ShipTo { get; set; }
            public CustomerInfo Soldto { get; set; }
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    namespace Model
    {
        public class CustomerInfo
        {
            public string Name1 { get; set; }
            public AddressModel Address { get; set; }
            public string Email { get; set; }
            public string Phone { get; set; }
        }
    }


    Maintenant je suis coincé, je ne sais pas comment indiquer à ma vue qu'un coup il faut prendre le "livré à" et l'autre le "payeur". Il doit falloir changer le DataContext selon le ViewModel utilisé, mais je ne sais pas comment faire.


    Je m'en remet donc à votre science

    Merci.

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 067
    Par défaut
    Pourquoi tu ne fais pas 2 vues mais qui pointe sur le même template, ça te simplifiera les choses.

  3. #3
    Membre averti
    Inscrit en
    Mars 2012
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 19
    Par défaut
    Merci de m'avoir lu.


    Pour simplifier la compréhension, je n'ai indiqué que le "livré à" et le "payeur".
    J'ai aussi le "facturé à", "commandé par" et je risque d'en avoir d'autres.

    Une seule vue gérée par plusieurs ViewModel m'allait très bien

  4. #4
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 056
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 056
    Par défaut
    Je comprends pas pourquoi tu as besoin de 2 view models différents s'il s'agit d'un même objet ( en gros une adresse à chaque fois ).
    Le problème d'avoir la même vue c'est que si des noms sont différents dans les view models alors les bindings ne fonctionneront pas. Si tu es sûr d'avoir les même noms& types, c'est donc qu'il s'agit du même view model!

  5. #5
    Membre averti
    Inscrit en
    Mars 2012
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 19
    Par défaut
    Je pense que vous avez raison, mais je ne sais pas comment faire.

    Pour être plus concret, voici ce que je souhaite refaire
    Nom : disco1.png
Affichages : 238
Taille : 26,2 Ko


    C'est une fenêtre comportant un TabControl.
    Je souhaite que chaque TabItem soit composé d'un UserControl car ca sera plus simple à modifier/gérer.

    Le 1er TabItem est "Information de Base", ce sera un UserControl et il comportera 4 boutons "livré à", "vendu à", "facturé à" et "payeur".
    Sous ces boutons, en encadré rouge, ira un autre UserControl que je souhaiterai être unique pour afficher les coordonnées selon le bouton cliqué.

    Par ex, le bouton "vendu à" ressemblera à ceci :
    Nom : Disco2.png
Affichages : 291
Taille : 24,0 Ko


    Je n'ai pas trouvé d'autre moyen que de passer par 1 ViewModel par bouton pour afficher un 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
    37
    38
    39
    40
    <UserControl x:Class="Discovery.View.Discovery_BaseInfoView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:ViewModel="clr-namespace:ViewModel"
                 xmlns:View="clr-namespace:Discovery.View">
     
        <UserControl.Resources>
            <DataTemplate DataType="{x:Type ViewModel:Discovery_ShipToViewModel}">
                <View:Discovery_CustomerInfoView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type ViewModel:Discovery_SoldToViewModel}">
                <View:Discovery_CustomerInfoView />
            </DataTemplate>
        </UserControl.Resources>
     
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="40"/>
                <RowDefinition />
            </Grid.RowDefinitions>
     
            <ListBox Grid.Row="0" Name="LstCustomerInfo" ItemsSource="{Binding SubMenus}" SelectedIndex="0">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
     
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}" Padding="10" VerticalAlignment="Center"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
     
            <GroupBox Grid.Row="1">
                <ContentControl Content="{Binding ElementName=LstCustomerInfo, Path=SelectedItem}"/>
            </GroupBox>
        </Grid>
    </UserControl>
    Grâce à cela, j'affiche ici 2 boutons et lorsque je clique sur l'un, ca affiche le UserControl que je souhaite via les DataTemplate en ressources.
    Le problème c'est comment lui passer les bonnes données.



    Il y a peut être une autre façon de faire et dans ce cas, je veux bien que l'on m'aiguille

  6. #6
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2009
    Messages
    2 056
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2009
    Messages : 2 056
    Par défaut
    Je te propose une description de code je n'ai pas le temps pour du vrai.

    L'idée c'est d'avoir dans ton BaseInfoView 2 propriétés de type CustomerInfo (enfin tu le nommes comme tu veux ce sont toutes les infos d'un payeur/acheteur). Ainsi que deux propriétés de type bool : IsShipVisible et IsSoldVisible.

    Dans BaseInfoView tu instancies 2 usercontrols CustomerInfoView,que tu bindes sur chacun de tes CustomerInfo (tu les superposes dans une grille, ou tu les mets dans un stackpanel pour débug, peu importe...) et dont tu bindes également la propriété "Visible" sur le IsShipVisible/IsSoldVisible (avec un converter BoolToVisibility).

    Le clique sur l'un des boutons (par commande donc puisque tu utilises MVVM) va simplement te permettre de mettre en vrai/faux les IsShipVisible/IsSoldVisible. Regardes également les CanExecute des commandes de manière à avoir tes boutons grisés en fonction du mode courant.

    Edit: Finalement puisqu'il s'agit de la même vue tu peux également n'utiliser qu'une seule vue que tu bindes sur une propriété du style CurrentCustomerInfo.
    Tes boutons ne feront que mettre à jour ce CurrentCustomerInfo (il faut être sûr d'avoir implémenté InotifyPropertyChanged) avec la bonne instance du CustomerInfo!

Discussions similaires

  1. Grid : Une row pour les remplir tous x)
    Par Arnard dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 04/03/2013, 09h57
  2. Réponses: 10
    Dernier message: 26/03/2008, 22h37
  3. Utulisation d'une table pour les jointure ( probleme )
    Par Boumeur dans le forum Langage SQL
    Réponses: 8
    Dernier message: 11/04/2005, 15h21
  4. Créer une vue pour trier une requete UNION ?
    Par Etienne Bar dans le forum SQL
    Réponses: 3
    Dernier message: 03/01/2003, 20h22

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