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 :

Refresh content d'un tabItem


Sujet :

Windows Presentation Foundation

  1. #1
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut Refresh content d'un tabItem
    Bonjour à tous

    Je vous expose mon pb.
    Je développement une application WPF MVVM.
    Je me sers d'un TabControl pour jouer le rôle d'un MDI.

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     <TabControl x:FieldModifier="public" IsSynchronizedWithCurrentItem="True" Margin="0,29,0,23" Name="tabControl2" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Tabs}" SelectedIndex="{Binding TabSelect}" Background="#00000000">
            </TabControl>

    Pour charger de manière dynamique mes tabItem, j'utilise une observableCollection<TabItem>

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
     
    private ObservableCollection<TabItem> _tabs = new ObservableCollection<TabItem>();
     
    public ObservableCollection<TabItem> Tabs
            {
                get { 
                    return _tabs; 
                }
                set
                {
                    _tabs = value;
                    RaisePropertyChanged("Tabs");
                }
            }


    Pour changer le contenu d'un tab ou en ajouter un, j'ajoute un TabItem à ma collection

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     newTabItem.Name = type;
    newTabItem.Header = table;
    newTabItem.Content = new View
    _tabs[index] = newTabItem;
    RaisePropertyChanged("Tabs");

    ou

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    TabItem newTabItem = new TabItem();
    newTabItem.Name = "ListeValeurs";
    newTabItem.Header = "Liste Valeurs";
    newTabItem.Content = new View;
    _tabs.Add(newTabItem);
    RaisePropertyChanged("Tabs");

    Le soucis : lorsque j'affiche un nouveau TabItem avec une View comme contenu pour la 1° fois pas de soucis, si je change le content d'un TabItem pas de soucis mais si j'essai de faire un refresh d'un content d'un TabItem (en rechargeant le même View) ou si je réaffiche un nouveau TabItem que j'avais déjà affiché : dans ces 2 derniers cas, aucun refresh.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    newTabItem.Content = new View
    Ne repasse pas par l'initialisation de la View

    Comment faire, les solutions trouvées sur le NET me paraissent flous ou imcompréhensibles.

    Merci de votre aide


    cdt
    Mickeybond

  2. #2
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Bonsoir Mickey,

    Je n'arrive pas à reproduire ton soucis de rafraîchissement. J'ai repris ton code (collection et xaml)

    Voici mon code

    Code c# : 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
    public TabItem newTabItem;
    private void btAdd_Click(object sender, RoutedEventArgs e)
    {
    	newTabItem = new TabItem();
    	newTabItem.Name = "ListeValeurs";
    	newTabItem.Header = "Liste Valeurs  " + i++;
    	newTabItem.Content = new View();
    	Tabs.Add(newTabItem);	
    }
     
    private void btModify_Click(object sender, RoutedEventArgs e)
    {
    	//changement total du contenu
    	newTabItem.Content = new View2();
    	//ou
    	//modification di contenu
    	TabItem newTabItem = Tabs[1];	
    	View v = newTabItem.Content as View;
    	v.lb.Content = "modification";
    }

    Mes modifications sont bien prises en compte...
    Ou alors je suis pas sur ton problème

  3. #3
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Bonjour Koyot3

    En fait, je voudrais réinitialiser le usercontrol dans mon TabItem et dans ce cas précis, c'est comme s'il était déjà en mémoire et donc pas de réinitialisation du content, il me raffiche le usercontrol sans passer par la case Init.

    En plus dans ton cas tu n'es pas en MVVM ?

  4. #4
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Re,

    Mon code serait similaire en MVVM sauf pour les deux events sur le click qui seraient des ICommands.

    Dans mon exemple, quand je fais le newTabItem.Content = new View2(); il recharge bien une nouvelle View2 dans mon tabitem.

    Sinon tu peux récupérer le Content de ton tabcontrol, tu le cast en UserControl de ton type et tu peux appeler dessus une méthode de Reset.

    Ta case Init, tu la situes ou ?

  5. #5
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Si je charge dans le conten un view2 cela fonctionne mais je souhaite faire un refresh de mon view1 qui a changé entre temps suite a des modifications sur un autre tabitem
    Et dans ce cas la si je refais un nouveau 'new view1()' il ne le recharge pas comme s il l avait encore en memoire

  6. #6
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Ça ne serait pas le datacontext de ta View1 qui poserait soucis ?

    Comment associes-tu la View1 à sa viewmodel ? Cette dernière doit être identique (1 seule instance pour tous View1)...

  7. #7
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Je te mettrais ça demain matin ... la je ne suis plus devant mon appli

  8. #8
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Dans app.xaml
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <Application.Resources>
            <vm:ServiceLocator xmlns:vm="clr-namespace:Utils" x:Key="ServiceLocator" />
    </Application.Resources>

    Sur ma page XAML
    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    DataContext="{Binding Source={StaticResource ServiceLocator}, Path=ViewModel1}"

    Class ServiceLocator.cs
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    private ViewModel1 TBA;
     public ViewModel1 ViewModel1
            {
                get
                {
                    if (TBA == null) TBA = new ViewModel1();
                    return TBA;
                }
            }


    de plus, si je reprend ton exemple pour le changement d'un content:
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    TabItem newTabItem = Tabs[1];	
    	View v = newTabItem.Content as View;
    	v.lb.Content = "modification";
    Tu ne changes que la valeur d'un label, moi je veux faire une réinitialisation totale de la page car je dois executer de nouveau des requetes sur la base de données et les afficher dans mon Datagrid

  9. #9
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Salut de bon matin

    En gros si j'ai bien compris, tu ouvres une View1 dans un TabItem 1, tu modifies des valeurs dedans et lors d'une action tu veux réinitialiser la View1 à ses valeurs d'origines, c'est bien cela ?

    Ce qui fait que quand tu réassignes ta new View1 à un autre tabitem il te garde les mêmes valeurs que celle modifiée ?

  10. #10
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Salut
    Non ce n'est pas ça.

    J'ai une MainWindows avec un tabControl
    J'ajoute des Tabitems dans mon viewModel.
    Dans le TabItem1 j'ai un userControl qui est la View1
    dans la view1 j'ai un bouton qui va ajouter un nouveau Tabitem pour visualiser un View2 (j'utilise messenger de mvvm light toolkit pour passer le message du usercontrol à la mainwindows)

    Puis quand je valide mes actions dans la View2, j'envoi un light messenger sur la mainWindows pour fermer le TabItem2 après sauvegarde des données et mettre à jour la View1.

    et la impossible de faire le refresh de la View1

  11. #11
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Tu es sûr que lorsque tu valides dans la View2, les modifications sont bien apportées sur la viewmodel qui est en datacontext de ta View1 ?

    Ton servicelocator fonctionne en mode singleton ce qui fait que chaque instance de ta View1 va pointer sur une seule et unique instance de viewmodel1 (sauf si tu forces la création) donc par exemple si tu appeles une méthode Reset sur ta viewmodel1, toutes les view1 doivent être rafraichies.

    Testé chez moi et pas de soucis en particulier

  12. #12
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Citation Envoyé par koyot3 Voir le message
    Tu es sûr que lorsque tu valides dans la View2, les modifications sont bien apportées sur la viewmodel qui est en datacontext de ta View1 ?

    Non c'est bien la le pb ... Lorsque je click sur le bouton dans ma View2, j'ai un mvvm light messenger à la mainWindows qui exécute un code qui ferme le tabItem de la View2 (la ça fonctionne).
    Après cela comme je veux faire un refresh de la View1, je réinitialise le TabITem dans mon observablecollection avec Ma View1 comme content, mais rien ne se passe... il ne repasse pas par le ViewModel1.

    Autre question : comment faire pour ne pas être en mode singleton? est-ce que ça changerait la donne?

  13. #13
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    C'est donc bien un problème de datacontext

    Dans ta View2, lorsque tu clics sur ton bouton, tu envoies 2 messages :
    - 1 ->MainViewModel pour lui dire de fermer ton TabItem2
    - 2 -> View1ViewModel pour lui dire de mettre à jour tes données

    Ainsi tous tes View1 seront mises à jour !

    Pour le mode singleton, c'est un choix à faire !
    Mode singleton = tu auras une seule instance de viewmodel, toutes les views l'utilisant auront les mêmes valeurs pour leurs bindings et si tu modifies une propriété bindée sur une view, toutes les autres auront la nouvelle valeur (même datacontext)

    Mode normal = chaque view aura sa propre instance de viewmodel et donc les modifications effectuées par une view (en binding) ne seront pas transmises automatiquement aux autres views (datacontext différent)

    Pour passer en mode "normal" en conservant ton Locator,

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     public ViewModel1 ViewModel1
            {
                get
                {                
                    return  new ViewModel1();
                }
            }

  14. #14
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Merci vraiment pour ton aide
    mais j'avais pensé à cette solution cependant elle me pose un autre pb.

    Lorsque j'instancie la réception du message dans l'initialisation du ViewModel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Messenger.Default.Register<String>(this, delegate(String msg)
                    {
                        OCList(msg);  
                    });
    je suis obligé d'ajouter un flag sous forme de properties sinon à chaque fois que je passe par l'Init du ViewModel je créé une nouvelle instance de message :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     if ((Application.Current.Properties["flag"]==null))
    Lorsque j'essai avec un flag de type private dans le view model il est réinitialisé à chaque fois.

    ça va donc me couter chez en variable d'application si je dois en mettre une dans chaque ViewModel

  15. #15
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Tu fonctionnes actuellement en mode singleton, donc tu peux laisser tes registers de messages dans ton constructeur.

    En plus le Messenger.Default fonctionne aussi en mode singleton

  16. #16
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Oui sauf que si je fais ça à chaque fois que je rappel mon viewModel à l'initialisation il me construit une nouvelle instance messenger donc autant de passage = autant de fois que le message sera executé.

  17. #17
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Ben tu as une seule instance de ton ViewModel1.
    Quand tu lui envoie un message pour le réinitialiser, je suppose que tu as une méthode "Reset" et donc à la réception d'un message, la viewmodel va appeler la méthode Reset qu'une fois.

    Si tu as plusieurs instances, chacune va recevoir le message.

    Je ne vois pas où est ton soucis à l'initialisation. ou alors c'est ton Reset qui est à revoir

  18. #18
    Membre averti
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Merci beaucoup pour ta patience et toutes tes explications.
    Effectivement avec ta solution ça fonctionne correctement.

    Mais je t'explique plus en détail mon petit soucis

    j'ouvre un tabItem1 avec View1
    puis j'ouvre un tabItem2 avec View2 (construteur du View2 load) à partir du View1
    Je change le contenu de mon tabItem2 avec un View3
    je fais mes traitements dans mon VIew3 et je demande à réafficher dans mon tabItem mon View2 (construteur du View2 load).
    Le constructeur a été exécuté 2 fois et bizarrement d'après ce que j'ai constaté le messenger est resté en mémoire la 1° fois et donc j'ai 2 messenger pour la View2.

    Encore merci de ton aide ...

  19. #19
    Membre éclairé Avatar de koyot3
    Inscrit en
    Avril 2007
    Messages
    693
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 693
    Par défaut
    Ah je comprend mieux ton soucis.
    Le hic c'est que tu fais recevoir ton message de reset dans ta view2 et non dans sa viewmodel2 !

    Normalement c'est la viewmodel qui reçoit le message, se met à jour et donc par la même occasion le binding met à jour ta/tes views 2... Et comme tu es en singleton, tu ne passe qu'une fois dedans

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 09/04/2013, 10h18
  2. Gestion de l'ajout de content dans un TabItem
    Par Tod_sd dans le forum Windows Presentation Foundation
    Réponses: 10
    Dernier message: 15/04/2009, 10h22
  3. Changer par code le content du refresh
    Par dadpub dans le forum Balisage (X)HTML et validation W3C
    Réponses: 9
    Dernier message: 06/07/2007, 16h23
  4. Redirection automatique avec http-equiv="Refresh" content="6001
    Par lodan dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 26/02/2007, 15h42
  5. Sortir d'un progamme qui boucle ou qui refresh
    Par mikevador02 dans le forum C
    Réponses: 12
    Dernier message: 14/12/2002, 09h38

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