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 :

liaison propertychanged d'une liste de textbox avec un label


Sujet :

Windows Presentation Foundation

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 246
    Par défaut liaison propertychanged d'une liste de textbox avec un label
    Décidément se mettre au WPF c'est difficile, on pense tout comprendre qd on tombe sur un os.

    Voici mon nouveau problème. J'ai une listView qui possède des textBox, lorsque je saisie dans un des text box, je souhazit qu'un label se mette à jour. Ce label récupère l'addition des contenus des textbox.

    voici ma listView

    Code xaml : 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
     
     
     <ListView Grid.Row="0" Margin="0,0,0,0" Name="listViewMontantSaisi" 
                                  ItemsSource="{Binding}" VerticalAlignment="Top"
                                  Focusable="True"  
                                  KeyboardNavigation.TabNavigation="Continue">
                        <!--<ListView Grid.Row="0" Name="listViewMontantSaisi"    MinHeight="120"  ItemsSource="{Binding}"
                                    IsSynchronizedWithCurrentItem="True" SelectedValuePath="HEURE"  Margin="0,0,0,-32.96" Grid.RowSpan="2" HorizontalAlignment="Left">-->
                         <ListView.ItemContainerStyle>
                                <Style TargetType="{x:Type ListViewItem}">
                                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                                    <Setter Property="Height" Value="28" />
                                    <Style.Triggers >
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                            <Setter Property="Background" Value="AliceBlue" ></Setter>
                                        </Trigger>
                                        <Trigger Property="ItemsControl.AlternationIndex" Value="2">
                                            <Setter Property="Background" Value="White"></Setter>
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </ListView.ItemContainerStyle>
                            <ListView.View >
                                <GridView AllowsColumnReorder="True">
                                    <GridViewColumn Width="100" Header="Code commune" DisplayMemberBinding="{Binding Path=codeCommune}"/>
                                    <GridViewColumn Width="100" Header="Code NAF" DisplayMemberBinding="{Binding Path=codeNAF}"  />
     
                                    <GridViewColumn Width="auto" >
                                        <GridViewColumnHeader Content="Montant VT déclaré" />
                                        <GridViewColumn.CellTemplate >
                                            <DataTemplate >
                                                <Control x:Name="controlMontantDeclare"  >
                                                    <Control.Template >
                                                        <ControlTemplate >
                                                            <TextBlock Text="{Binding Path=montantDeclare, UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:n2}}"  TextAlignment="Right"/>                                                                                                            
                                                        </ControlTemplate>
                                                    </Control.Template>
                                                </Control>
                                                <DataTemplate.Triggers>
                                                    <DataTrigger
                                            Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"
                                            Value="True">
                                                        <Setter TargetName="controlMontantDeclare" Property="Template">
                                                            <Setter.Value>
                                                                <ControlTemplate>
                                                                    <TextBox IsEnabled="{Binding ElementName=listViewOrganismesCollecteurs, Path=SelectedValue, Mode=TwoWay, Converter={StaticResource ConverterIsEnabled2}}" Width="100" Name="textBoxMontantDeclare" Text="{Binding Path=montantDeclare, StringFormat={}{0:n2}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Converter={StaticResource ConverterNumerique}}" TextAlignment="Right" ></TextBox>
                                                                </ControlTemplate>
                                                            </Setter.Value>
                                                        </Setter>
                                                    </DataTrigger>
                                                </DataTemplate.Triggers>
                                            </DataTemplate>
                                        </GridViewColumn.CellTemplate>
                                    </GridViewColumn>
                                    <GridViewColumn Width="130">
                                        <GridViewColumnHeader Content="Effectifs"/>
                                        <GridViewColumn.CellTemplate>
                                            <DataTemplate>
                                                <Control x:Name="controlEffectif">
                                                    <Control.Template>
                                                        <ControlTemplate>
                                                            <TextBlock Text="{Binding Path=effectif, UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:n0}}"  TextAlignment="Right" Width="130"/>
                                                        </ControlTemplate>
                                                    </Control.Template>
                                                </Control>
                                                <DataTemplate.Triggers>
                                                    <DataTrigger
                                            Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"
                                            Value="True">
                                                        <Setter TargetName="controlEffectif" Property="Template">
                                                            <Setter.Value>
                                                                <ControlTemplate>
                                                                    <TextBox  IsEnabled="{Binding ElementName=listViewOrganismesCollecteurs, Path=SelectedValue, Mode=TwoWay, Converter={StaticResource ConverterIsEnabled2}}" Name="textBoxEffectif" Width="130" Text="{Binding Path=effectif, Mode=TwoWay, Converter={StaticResource ConverterNumerique}, UpdateSourceTrigger=PropertyChanged, StringFormat={}{0:n0}}" ></TextBox>
                                                                </ControlTemplate>
                                                            </Setter.Value>
                                                        </Setter>
                                                    </DataTrigger>
                                                </DataTemplate.Triggers>
                                            </DataTemplate>
                                        </GridViewColumn.CellTemplate>
                                    </GridViewColumn>
     
                                </GridView>
                            </ListView.View>
                        </ListView>

    et voici mon label qui récupère l'addition de la liste de textBox "textBoxMontantDeclare":

    Code xaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <Label Grid.Column="1" Content="Montant déclaré" Height="28" HorizontalAlignment="Left" Margin="0,0,0,0" Name="label4" VerticalAlignment="Top"  />
                            <Label Grid.Column="2" Height="23" Name="labelMontantDeclare" VerticalAlignment="Top" HorizontalAlignment="Right"       
                                   Content="{Binding ElementName=listViewMontantSaisi, Path=ItemsSource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ConverterSommeMontantsDeclares}}" ContentStringFormat="{}{0:n2}" />


    Je ne passe dans mon converter que lorsque ma listView se charge, alors qu'il faudrait à chaquefois que le Text de la textBox change?

    Merci

  2. #2
    Membre éprouvé
    Inscrit en
    Juin 2008
    Messages
    162
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 162
    Par défaut
    C'est plutot normal vue que le binding n'est mis a jour que quand la collection des items de la ListView change.

  3. #3
    Membre éclairé
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2007
    Messages
    246
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Février 2007
    Messages : 246
    Par défaut
    Après plusieurs essais infructueux j'ai essayé de mettre en place un INotifyPropertyChanged.

    Donc j'ai une classe VTVersement qui hérite de INotifyPropertyChanged, et une classe VTVersementTotal qui posède un collection d'objet VTVersement et qui hérite elle aussi de INotifyPropertyChanged

    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
    121
    class VTVersementTotal : INotifyPropertyChanged
        {
     
            private ObservableCollection<VTVersement> _listeVersement;
            public ObservableCollection<VTVersement> ListeVersement
            {
                get { return _listeVersement; }
                set {
                    _listeVersement = value;
                    RaisePropertyChanged("ListeVersement");
                    }
            }
     
            private string _totalMontantDeclare;
            public string TotalMontantDeclare
            {
                get {
                    _totalMontantDeclare = "0";
                    foreach (VTVersement child in ListeVersement)
                    {
                       _totalMontantDeclare  = (Convert.ToDouble(child.MontantDeclare) + Convert.ToDouble(_totalMontantDeclare)).ToString();
                    }
                    return _totalMontantDeclare;
                    }
                set { _totalMontantDeclare = value; }
            }
     
     
            private string _totalEffectif;
            public string TotalEffectif
            {
                get {
                    _totalEffectif = "0";
                    foreach (VTVersement child in ListeVersement)
                    {
                        _totalMontantDeclare = (Convert.ToDouble(child.Effectif) + Convert.ToDouble(_totalEffectif)).ToString();
                    }
                    return _totalEffectif; 
                    }
                set
                {
                    _totalEffectif = value;
                }
            }
     
     
     
            public event PropertyChangedEventHandler PropertyChanged;
            public bool modifie = false;
     
            private void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged == null)
                {
                    return;
                }
                else
                    modifie = true;
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
     
            public VTVersementTotal()
            {
                ListeVersement = new ObservableCollection<VTVersement>();
                PropertyChanged = ChildPropertyChanged;
     
                ListeVersement.CollectionChanged += delegate(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
                {
                    // Subscribe event
                    switch (e.Action)
                    {
                        case NotifyCollectionChangedAction.Add:
                            // Subscribe
                            foreach (INotifyPropertyChanged propertyChanged in e.NewItems)
                            {
                                propertyChanged.PropertyChanged += PropertyChanged;
                            }
                            break;
     
                        case NotifyCollectionChangedAction.Remove:
                            // Unsubscribe
                            foreach (INotifyPropertyChanged propertyChanged in e.OldItems)
                            {
                                propertyChanged.PropertyChanged -= PropertyChanged;
                            }
                            break;
                    }
                };
     
            }
     
            /// <summary>
            /// Handles the PropertyChanged event of the Child control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
            private void ChildPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                // Si le montant de l'objet enfant a été modifié (), on informe la propriété "TotalMontantDeclare" du parent
                // pour que le total se recalcule
                if (e.PropertyName == "MontantDeclare")
                {
                    OnPropertyChanged("TotalMontantDeclare");
                }
                if (e.PropertyName == "Effectif")
                {
                    OnPropertyChanged("TotalEffectif");
                }
            }
     
            /// <summary>
            /// Called when a property has changed.
            /// </summary>
            /// <param name="propertyName">Name of the property.</param>
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
     
        }
    }
    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
     
    class VTVersement : INotifyPropertyChanged
        {
     
            private string _codeCommune;
            public string CodeCommune
            {
                get { return _codeCommune; }
                set { _codeCommune = value; }
            }
     
            private string _codeNAF;
            public string CodeNaf
            {
                get { return _codeNAF; }
                set { _codeNAF = value; }
            }
     
            private string _montantDeclare;
            public string MontantDeclare
            {
                get { return _montantDeclare; }
                set { 
                    _montantDeclare = value;
                    RaisePropertyChanged("MontantDeclare");
                    }
            }
     
            private string _effectif;
            public string Effectif
            {
                get { return _effectif; }
                set { 
                    _effectif = value;
                    RaisePropertyChanged("Effectif");
                    }
            }
     
     
            public event PropertyChangedEventHandler PropertyChanged;
            public bool modifie = false;
     
            private void RaisePropertyChanged(string propertyName)
            {
                if (PropertyChanged == null)
                {
                    return;
                }
                else
                    modifie = true;
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     
            }
     
            public VTVersement()
            {
     
            }
     
        }
    }
    la classe VTVersement alimente ma liste "listViewMontantSaisi"

    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
     
     private void AfficherDonneesSaisies(long pOrganismeCollecteur, string pAnnee, string pMois)
            {
                // TabItem 2 : Saisie manuelle
                totalVersementDeclare.ListeVersement.Clear();
                ObservableCollection<CME_VT_MontantDeclare> listeMontantsDeclaresGroupesParCodeNAF = CME_VT_MontantDeclare.ListeMontantsDeclaresGroupesParCodeNAF(pOrganismeCollecteur, pAnnee, pMois);
                foreach (CME_VT_MontantDeclare ligne in listeMontantsDeclaresGroupesParCodeNAF)
                {
                    VTVersement versement = new VTVersement();
                    versement.CodeCommune = ligne.codeCommune;
                    versement.CodeNaf = ligne.codeNAF;
                    if (ligne.effectif != null)
                        versement.Effectif = ligne.effectif.ToString();
                    if (ligne.montantDeclare != null)
                        versement.MontantDeclare = ligne.montantDeclare.ToString();
                    totalVersementDeclare.ListeVersement.Add(versement);
     
                }
                listViewMontantSaisi.DataContext = totalVersementDeclare.ListeVersement;
                listViewMontantSaisi.ItemsSource = totalVersementDeclare.ListeVersement;
    Ma quistion c'est comment puis-faire dans mon code XAML pour que mon label "labelMontantDeclare" se met à jour quand je saisie une valeur dans ma textbox "textBoxMontantDeclare" de ma liste "listViewMontantSaisi" ?

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    415
    Détails du profil
    Informations personnelles :
    Âge : 59
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 415
    Par défaut
    En fait, plein de gens (dont je fais partie) se prennent vraiment la tête avec les bindings...
    ... ça fait gonfler le xaml à écrire
    ... et en plus il faut réimplémenter des classes pour les listes observables ou les INotifyPropertyChanged : pas forcément cool

    Du coup, j'utilise plutôt cette approche (qui n'est pas parfaite mais suffit souvent) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
         Label monLabelLieAuTextBox = ...;
         UneDonnee maDonneeLieeAuTextBox = ...;
         maTextBox.TextChanged += ( s, e ) =>
         {
             MettreAJourMaDonnee( maDonneeLieeAuTextBox, maTextBox.Text );
             MettreAJourMonLabel( maDonneeLieeAuTextBox, monLabelLieAuTextBox );
         };
    Pour le dire autrement, on profite de la liaison des variables locales dans le corps de la fonction anonyme pour retrouver ses petits lors de l'appel de l'événement.

Discussions similaires

  1. Table lié à une liste d'objet avec reclassement
    Par backseatgreg dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 10/03/2007, 08h41
  2. Réponses: 7
    Dernier message: 05/10/2006, 08h07
  3. Construire une liste de sélection avec 2 tables
    Par domdas dans le forum Requêtes
    Réponses: 1
    Dernier message: 11/08/2006, 14h15
  4. Tri d'une liste d'attente avec priorité
    Par boutchz dans le forum Access
    Réponses: 8
    Dernier message: 02/03/2006, 18h42
  5. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46

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