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 :

Mise à jour auto d'un TreeView


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de thelpi
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 217
    Par défaut Mise à jour auto d'un TreeView
    Bonjour à tous,

    j'essaye depuis quelques semaines maintenant de réaliser un treeview efficace, mais je rencontre encore quelques problèmes... voici mon code:

    le treeview XAML (1 racine, 1 niveau sans checkbox, 2 niveau avec checkbox):

    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
     
    <ScrollViewer>
                <DockPanel Height="400">
                    <DockPanel.Resources>
                        <local:ListCat x:Key="MyList"/>
                        <HierarchicalDataTemplate DataType="{x:Type local:Cat}" ItemsSource="{Binding Path=LstSsCat}">
                            <TextBlock Text="{Binding Path=Name}"/>
                        </HierarchicalDataTemplate>
                        <HierarchicalDataTemplate DataType="{x:Type local:SsCat}" ItemsSource="{Binding Path=LstProcess}">
                            <CheckBox IsChecked="{Binding Path=IsCheck}" Content="{Binding Path=Name}" />
                        </HierarchicalDataTemplate>
                        <DataTemplate DataType="{x:Type tsk:SyncProcessUnit}">
                            <CheckBox Content="{Binding Path=Name}" IsChecked="{Binding Path=Active}" />
                        </DataTemplate>
                    </DockPanel.Resources>
                    <TreeView Name="trvTasks">
                        <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" />
                    </TreeView>
                </DockPanel>
            </ScrollViewer>
    les objets sur lequel il est bindé (dsl pour le pavé ):

    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
     
    /// <summary>
        /// classe de binding pour les catégories de 1er niveau 
        /// </summary>
        class Cat
        {
            /// <summary>
            /// nom
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// liste des sous-catégories
            /// </summary>
            public List<SsCat> LstSsCat { get; set; }
     
            public Cat(string _name)
            {
                Name = _name;
                LstSsCat = new List<SsCat>();
            }
        }
        /// <summary>
        /// liste des catégories de 2ème niveau
        /// </summary>
        class SsCat
        {
            /// <summary>
            /// détermine si l'intégralité des processus de la catégorie est sélectionnée
            /// </summary>
            private bool isCheck;
            /// <summary>
            /// nom de la sous-catégorie
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// liste des processus de la catégorie
            /// </summary>
            public List<SyncProcessUnit> LstProcess { get; set; }
            /// <summary>
            /// accesseur sur isCheck
            /// </summary>
            public bool IsCheck
            {
                get { return isCheck; }
                set
                {
                    isCheck = value;
                    if (isCheck)
                    {
                        foreach (SyncProcessUnit p in LstProcess)
                        {
                            if (!p.Active)
                                p.Active = true;
                        }
                    }
                }
            }
     
            public SsCat(bool _check, string _name)
            {
                Name = _name;
                LstProcess = new List<SyncProcessUnit>();
                isCheck = _check;
            }
     
            /// <summary>
            /// recherche les processus actifs du groupe et valorise IsCheck si ils le sont tous
            /// </summary>
            public void SetActivation()
            {
                bool action = true;
                if (LstProcess.Count > 0)
                {
                    foreach (SyncProcessUnit p in LstProcess)
                    {
                        if (!p.Active)
                            action = false;
                    }
                }
                else
                    action = false;
                isCheck = action;
            }
        }
        /// <summary>
        /// classe de binding pour le TreeView
        /// </summary>
        class ListCat : List<Cat>
        {
            public ListCat()
            {
                foreach (SyncProcess prc in syncProcessManager.GetInstance())
                {
                    SyncProcess.SyncProcessGroup grp = (SyncProcess.SyncProcessGroup)prc;
                    if (grp.IsRoot)
                    {
                        int i = 0;
                        foreach (SyncProcess prc4 in grp.Processus)
                        {
                            SyncProcess.SyncProcessGroup grp3 = (SyncProcess.SyncProcessGroup)prc4;
                            this.Add(new Cat(grp3.Name));
                            int j = 0;
                            foreach (SyncProcess prc2 in grp3.Processus)
                            {
                                SyncProcess.SyncProcessGroup grp2 = (SyncProcess.SyncProcessGroup)prc2;
                                this[i].LstSsCat.Add(new SsCat(false, grp2.Name));
                                foreach (SyncProcess prc3 in grp2.Processus)
                                {
                                    SyncProcessUnit prc3Unit = (SyncProcessUnit)prc3;
                                    this[i].LstSsCat[j].LstProcess.Add(prc3Unit);
                                }
                                this[i].LstSsCat[j].SetActivation();
                                j++;
                            }
                            i++;
                        }
                    }
                }
            }
        }
    pas besoin de tout lire, la chose importante ici est la propriété IsCheck des Sous Catégories.
    Quand l'utilisateur coche une checkbox du niveau supérieur, tout les enfants voit leur propriété IsCheck passée également à True.
    Normalement comme la propriété IsCheck de chaque enfant est bindé sur leur checkbox respective, celles-ci devraient être instantanément cochées, malheureusement rien ne se produit graphiquement...

    je ne sais pas si j'ai été clair je peux préciser si besoin...

    Merci!

  2. #2
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Par défaut
    As-tu essayé d'utiliser des ObservableCollection à la place de tes List ?

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 214
    Par défaut
    Il faut également que tu supportes l'interface INotifyPropertyChanged, et que tu lèves l'évènement PropertyChanged quand tu fais le set de ta propriété.
    C'est de cette manière que le binding sera notifié du changement de la propriété.

  4. #4
    Membre confirmé Avatar de thelpi
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 217
    Par défaut
    Je viens d'essayer et rien a changé.

    En plus de convertir les Listes en collections observables,
    j'ai modifié cette ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <TreeView Name="trvTasks">
                        <TreeViewItem ItemsSource="{Binding Source={StaticResource odpTsk}}" />
    </TreeView>
    ajouté cette ligne dans les ressources de la page:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <ObjectDataProvider x:Key="odpTsk" />
    et celles-ci dans le constructeur de la fenêtre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ObjectDataProvider odpTsk = this.FindResource("odpTsk") as ObjectDataProvider;
                if (odpTsk != null)
                    odpTsk.ObjectInstance = new ListCat();
    j'ai ce genre de code dans d'autres pages, pour binder des ListBox, et ça marche très bien (cependant à aucun autre endroit de mon application j'ai des relations entre checkbox à traiter).

    Merci pour ton aide.

  5. #5
    Membre confirmé Avatar de thelpi
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 217
    Par défaut
    Effectivement, ça marche en implémentant INotifyPropertyChanged!

    merci beaucoup.

  6. #6
    Membre confirmé Avatar de thelpi
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    217
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Deux Sèvres (Poitou Charente)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 217
    Par défaut
    Le code pour ceux que ça intéresse (et pour moi car je ne suis pas sur de pouvoir refaire ça du premier coup la prochaine fois ^^)

    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    class SsCat
        {
            /// <summary>
            /// détermine si l'intégralité des processus de la catégorie est sélectionnée
            /// </summary>
            private bool isCheck;
            /// <summary>
            /// nom de la sous-catégorie
            /// </summary>
            public string Name { get; set; }
            /// <summary>
            /// liste des processus de la catégorie
            /// </summary>
            public ObservableCollection<SyncProcessUnit> LstProcess { get; set; }
            /// <summary>
            /// accesseur sur isCheck
            /// </summary>
            public bool IsCheck
            {
                get { return isCheck; }
                set
                {
                    isCheck = value;
                    if (isCheck)
                    {
                        foreach (SyncProcessUnit p in LstProcess)
                        {
                            if (!p.Active)
                            {
                                p.Active = true;
                                // ajout de cette ligne
                                p.OnNotifyPropertyChanged("Active");
                            }
                        }
                    }
                }
            }
     
            public SsCat(bool _check, string _name)
            {
                Name = _name;
                LstProcess = new ObservableCollection<SyncProcessUnit>();
                isCheck = _check;
            }
     
            /// <summary>
            /// recherche les processus actifs du groupe et valorise IsCheck si ils le sont tous
            /// </summary>
            public void SetActivation()
            {
                bool action = true;
                if (LstProcess.Count > 0)
                {
                    foreach (SyncProcessUnit p in LstProcess)
                    {
                        if (!p.Active)
                            action = false;
                    }
                }
                else
                    action = false;
                isCheck = action;
            }
        }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    public class SyncProcessUnit : INotifyPropertyChanged
    {
        public bool Active{ get; set; }
     
    public virtual void OnNotifyPropertyChanged(string propName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propName));
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
    }

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

Discussions similaires

  1. retirer l'alerte de mise à jour auto
    Par gretch dans le forum Windows XP
    Réponses: 2
    Dernier message: 09/10/2006, 09h35
  2. Mise à jour auto d'un site web, comment ?
    Par 123quatre dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 27/08/2006, 19h38
  3. Mise à jour auto MIDlet possible ?
    Par infotron dans le forum Java ME
    Réponses: 7
    Dernier message: 27/07/2006, 14h18
  4. [MS-DOS] Une commande DOS pour activer les mises à jour auto
    Par Furius dans le forum Scripts/Batch
    Réponses: 20
    Dernier message: 02/12/2005, 16h21
  5. Mise à jour auto champs date
    Par rodrigue50 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 25/07/2005, 17h03

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