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 :

[c#] Mettre à jour une propriété sur le changement d'une autre propriété


Sujet :

Windows Presentation Foundation

  1. #1
    Membre éprouvé Avatar de yonpo
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2010
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 617
    Points : 947
    Points
    947
    Par défaut [c#] Mettre à jour une propriété sur le changement d'une autre propriété
    Bonsoir à tous,

    D'abord voici deux classes :

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    public class Gamme
        {
            public string NomGamme { get; set; }
            public int Code { get; set; }
            private ObservableCollection<Produit> _produits = new ObservableCollection<Produit>();
            public ObservableCollection<Produit> Produits
            {
                get
                {
                    return _produits;
                }
                set
                {
                    _produits = value;
                }
            }
            private string _nbproduitachete;
            public string NbProduitAchete
            {
                get
                {
                    var query = (from element in Produits where element.EtatAchat == true select element);
                    _nbproduitachete = query.Count().ToString();
                    return _nbproduitachete;
                }
                set
                {
                    _nbproduitachete = value;
                }
            }
        }

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class Produit
        {
            public string NomProduit { get; set; }
            public bool EtatAchat { get; set; }
        }

    Ensuite, je binde une ObservableCollection<Gamme> à un ListBox dont voici le style appliqué (simplifié):
    Code xml : 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
     
    <Style x:Key="ListBoxItemGamme" TargetType="ListBoxItem">
                <Setter Property="SnapsToDevicePixels" Value="true"/>
                <Setter Property="OverridesDefaultStyle" Value="true"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border x:Name="Border"
                                    BorderBrush="#FF999999" Padding="3" Margin="5" BorderThickness="0.5" 
                                    Background="Transparent" CornerRadius="3">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        ...
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        ...
                                    </Grid.RowDefinitions>
                                    <TextBlock Text="{Binding NomGamme}" Grid.Column="2" Grid.ColumnSpan="8" FontSize="25" FontWeight="DemiBold"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"/>
     
                                    <TextBox Text="{Binding Code, Mode=TwoWay}" Grid.Column="3" Grid.Row="1"/>
                                    <TextBlock Text="{Binding NbProduitAchete}" Grid.Column="3" Grid.Row="2" />
     
                                    <Expander Grid.Row="8" Grid.ColumnSpan="10">
                                        <WrapPanel>
                                            <ItemsControl x:Name="itemsControl" ItemsSource="{Binding Produits}">
                                                <ItemsControl.ItemsPanel>
                                                    <ItemsPanelTemplate>
                                                        <WrapPanel/>
                                                    </ItemsPanelTemplate>
                                                </ItemsControl.ItemsPanel>
                                                <ItemsControl.ItemTemplate>
                                                    <DataTemplate>
                                                        <Border x:Name="borderVol" Padding="2,2,5,2" Margin="3" BorderThickness="0.5" Background="Transparent" 
                                                                CornerRadius="3">
                                                            <Grid>
                                                                <Grid.ColumnDefinitions>
                                                                    ...
                                                                </Grid.ColumnDefinitions>
                                                                <Grid.RowDefinitions>
                                                                    ...
                                                                </Grid.RowDefinitions>
                                                                <TextBlock Grid.Column="1" Text="{Binding NomProduit}"/>
                                                                <ToggleButton Grid.Column="1" Grid.Row="3" Style="{StaticResource TooglButtonEtatAchat}"/>
                                                            </Grid>
                                                        </Border>
     
                                                        <DataTemplate.Triggers>
                                                            ...
                                                        </DataTemplate.Triggers>
                                                    </DataTemplate>
                                                </ItemsControl.ItemTemplate>
                                            </ItemsControl>
                                        </WrapPanel>
                                    </Expander>
     
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                ...
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

    Et enfin le style du ToogleButton présent dans le style ci-dessus
    Code xml : 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
     
    <!-- Style ToogleButton-->
        <Style x:Key="TooglButtonEtatAchat" TargetType="{x:Type ToggleButton}">
            <Setter Property="SnapsToDevicePixels" Value="true"/>
            <Setter Property="OverridesDefaultStyle" Value="true"/>
            <Setter Property="IsChecked" Value="{Binding EtatAchat}"/>
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Image x:Name="imgEtat" Source="../Images/buy_no.png" Width="32" Height="32"
                                   ToolTip="Produit non acheté"/>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Cursor" Value="Hand"/>
                            </Trigger>
                            <DataTrigger Binding="{Binding EtatAchat}" Value="True">
                                <Setter TargetName="imgEtat" Property="Source" Value="../Images/buy_ok.png"/>
                                <Setter TargetName="imgEtat" Property="ToolTip" Value="Produit acheté"/>
                            </DataTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    Ceci fait, lors d'un clic sur le ToggleButton, ma propriété EtatAchat est bien mis à jour (true/false).

    Je souhaite que la propriété NbProduitAchete de la classe Gamme soit elle aussi mise à jour quand EtatAchat l'est.

    En gros :
    • Un clic sur ToggleButton =>
    • Changement de la valeur de EtatAchat (true/false) =>
    • Changement de la valeur de NbProduitAchete qui correspond au nombre de Produit ayant la propriété EtatAchat à true


    J'ai pensé à mettre ça dans le set de NbProduitAchete :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var query = (from element in Produits where element.EtatAchat == true select element);

    Ainsi, j'obtiens bien ce que je veux, or ceci n'est pas effectué au changement de la propriété EtatAchat.

    Merci de m'aider ou de m'indiquer une autre façon de faire...
    J'espère avoir été clair.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Tu implémentes l'interface INotifyPropertyChanged dans la classe Gamme et dans la classe Produit. Une fois cela fait, dans la classe Gamme tu t'abonnes à l'évènement ProperyChanged de chaque Produit appartenant à ta collection et dans la gestionnaire tu regardes s'il s'agit de la propriété EtatAchat qui est à l'origine du déclenchement de l'"évènement. Si oui tu implémentes la logique que t'as citée dans ton premier post.
    J'espère avoir bien expliqué.

  3. #3
    Membre éprouvé Avatar de yonpo
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2010
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 617
    Points : 947
    Points
    947
    Par défaut
    Merci pour ta réponse
    Citation Envoyé par h2s84 Voir le message
    Tu implémentes l'interface INotifyPropertyChanged dans la classe Gamme et dans la classe Produit.
    Ok
    Citation Envoyé par h2s84 Voir le message
    Une fois cela fait, dans la classe Gamme tu t'abonnes à l'évènement ProperyChanged de chaque Produit appartenant à ta collection
    Justement. Comment s'abonner dans la classe Gamme à l'évènement PropertyChanged qui se trouve dans la classe Produit ?

  4. #4
    Membre éprouvé Avatar de jmix90
    Homme Profil pro
    Consultant .Net
    Inscrit en
    Juillet 2007
    Messages
    576
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Consultant .Net
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2007
    Messages : 576
    Points : 998
    Points
    998
    Par défaut
    Citation Envoyé par yonpo Voir le message
    Justement. Comment s'abonner dans la classe Gamme à l'évènement PropertyChanged qui se trouve dans la classe Produit ?
    Lorsque tu settes la collection de Produit, tu peux la parcourir et t'abonner à chaun des éléments la constituant. Pense bien à te désabonner des éléments de l'ancienne collection.

    Bon courage,

  5. #5
    Invité
    Invité(e)
    Par défaut
    Suis les étapes suivantes :
    1. tu t'abonnes à l'évènement CollectrionChanged de ta collection Produits comme suit :
      Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
       
      this.Produits.CollectionChanged += ProduitsCollectionChanged;
    2. L'implémentation de ton gestion ProduitsCollectionChanged doit avoir cette tête :
      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
      21
       
      private void ProduitsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
      {
       
      	if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
      	{
      		// On s'abonne à l'évènement PropertyChanged de chaque produit ajouté à la collection
      		foreach (Product item in e.NewItems)
      		{
      			item.PropertyChanged += itemPropertyChanged;
      		}
      	}
      	else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
      	{
      		// On se d'sabonne de l'évènement PropertyChanged de chaque produit retiré de la collection
      		foreach (Product item in e.OldItems)
      		{
      			item.PropertyChanged -= itemPropertyChanged;
      		}
      	}            
      }
    3. Enfin pour le gestionnaire de itemProperytChanged c'est simple, il a cette tête :
      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 void itemPropertyChanged(object sender, PropertyChangedEventArgs e)
      {
      	switch(e.PropertyName)
      	{
      		case "EtatAchat":
      			  // ma logique
      			break;
       
      		//...
       
      		case "Propriété n":
      			break;
      	}
      }


    [EDIT] Cette méthode suppose que tu utilises les méthodes Add et Remove pour respectivement ajouter et supprimer des éléments dans ta collection.

    Par contre tu fais une assignation directe d'une liste de produits à ta collection il va falloir parcourir après la liste des produits et s'abonner à l'évènement PropertyChanged de chaque produit de la nouvelle collection.

    Le code issu des étapes citées plus haut reste toujours utiles vu que tu seras amené à ajouter de nouveaux produits à la collection et t'évites de parcourir la liste à nouveau. De plus il retire l'abonnement à l'évènement si le produit est supprimé de la collection.
    [/EDIT]
    Dernière modification par Invité ; 26/08/2011 à 11h15.

  6. #6
    Membre éprouvé Avatar de yonpo
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2010
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 617
    Points : 947
    Points
    947
    Par défaut
    Ok merci à vous deux.

    Je regarderai ça ce soir...

  7. #7
    Membre éprouvé Avatar de yonpo
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2010
    Messages
    617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 617
    Points : 947
    Points
    947
    Par défaut
    Voici le code final. Le résultat est celui que je souhaitais.

    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
    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
     
    public class Gamme : INotifyPropertyChanged
        {
            public Gamme()
            {
                this.Produits.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Produits_CollectionChanged);
            }
            public string NomGamme { get; set; }
            public int Code { get; set; }
            private ObservableCollection<Produit> _produits = new ObservableCollection<Produit>();
            public ObservableCollection<Produit> Produits
            {
                get
                {
                    return _produits;
                }
                set
                {
                    _produits = value;
                }
            }
            private string _nbproduitachete;
            public string NbProduitAchete
            {
                get
                {
                    var query = (from element in Produits where element.EtatAchat == true select element);
                    _nbproduitachete = query.Count().ToString();
                    return _nbproduitachete;
                }
                set
                {
                    _nbproduitachete = value;
                    NotifyPropertyChanged("NbProduitAchete");
                }
            }
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            private void NotifyPropertyChanged(string info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
     
            private void Produits_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
     
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    // On s'abonne à l'évènement PropertyChanged de chaque produit ajouté à la collection
                    foreach (Produit item in e.NewItems)
                    {
                        item.PropertyChanged += itemPropertyChanged;
                    }
                }
                else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                {
                    // On se désabonne de l'évènement PropertyChanged de chaque produit retiré de la collection
                    foreach (Produit item in e.OldItems)
                    {
                        item.PropertyChanged -= itemPropertyChanged;
                    }
                }
            }
     
            private void itemPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                var query = (from element in Produits where element.EtatAchat == true select element);
                NbProduitAchete = Convert.ToString(query.Count());
            }
        }

    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
    21
    22
    23
    24
    25
    26
    27
     
    public class Produit : INotifyPropertyChanged
        {
            public string NomProduit { get; set; }
            private bool _etatachat;
            public bool EtatAchat
            {
                get
                {
                    return _etatachat;
                }
                set
                {
                    _etatachat = value;
                    NotifyPropertyChanged("EtatAchat");
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
     
            private void NotifyPropertyChanged(string info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
        }

    Dans itemPropertyChanged, je ne teste pas quelle est la propriété qui a déclenché l'évènement car la notification est faite que sur EtatAchat.
    Mais je garde ta solution sous le coude, j'en aurai surement besoin un jour.

    En tout cas, merci pour ton aide, cela faisait un moment que je cherchais.
    Merci

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 10/01/2014, 11h13
  2. [XL-2003] Activer une sub sur le changement d'une valeur de cellule
    Par Claude_B dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 19/12/2011, 23h32
  3. [WCF] notification sur le changement d'une propriété.
    Par maa dans le forum Windows Communication Foundation
    Réponses: 6
    Dernier message: 23/03/2008, 11h19
  4. Réponses: 7
    Dernier message: 26/05/2006, 19h45
  5. Mettre à jour la franchise sur une requête
    Par soso78 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 22/10/2005, 11h18

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