Valeurs d'une textbox liée à celle d'une autre [Résolu]

Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
- - Dernière réponse : babaOrhumette
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
- 7 avril 2019 à 17:16
Bonjour,
J'aimerais lier une textbox à une autre automatiquement, je tente de m'expliquer.
Mon code possède 2 textbox : textBox1 et textBox2.
J'aimerais que les valeurs (numériques) de la textBox1 varient en fonction de celles de la textbox2 et réciproquement.
Que ce soit dynamique (je ne suis pas certaines du terme).

Par exemple :
Lorsque je mets manuellement la valeur 2 à la textBox1, la textBox2 change automatiquement ces valeurs en 4.
Et lorsque j'indique 6 à valeur de la textBox2 la textBox1 donne 3.

Est-ce possible ?
Merci.
Afficher la suite 

Votre réponse

3 réponses

Messages postés
14423
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 avril 2019
155
0
Merci
Regardes l’événement "Change" sur les TextBox.
Commenter la réponse de NHenry
Messages postés
13134
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
21 avril 2019
354
0
Merci
Bonjour

tu peux aussi profiter du fait que C# est pensé pour la liaison de données (binding).

Tu écris une classe "métier" dont le job est de virtualiser un objet réel, une action, un concept.
Tu bindes ensuite une instance ou une collection de cette classe sur ton formulaire.

Par exemple, un prix , c'est un prix unitaire hors taxe, un taux de TVA, un prix unitaire TTC, une quantité et un prix total, réduisons au prix hors taxe et ttc.
    public class Prix
    {
        private double taux = 0.2;

        private double ht;

        public double HT
        {
            get { return ht; }
            set
            {
                ht = value;
                TTC = ht * (1.0 + taux);
            }
        }

        private double ttc;

        public double TTC
        {
            get { return ttc; }
            set
            {
                ttc = value;
                HT = ttc / (1.0 + taux);
            }
        }

    }

Quand on saisie la propriété HT ça calcule automatiquement TTC, et quand on saisie TTC, ça calcule automatiquement HT.
Le hic, pour l'instant, c'est qu'on va rentrer dans une boucle sans fin, si tu saisie l'un ça saisie l'autre qui ressaisie l'un qui ressaisie l'autre etc...
Faut donc mettre un filet
    public class Prix
    {
        private double taux = 0.2;

        private double ht;

        public double HT
        {
            get { return ht; }
            set
            {
                if (ht != value)
                {
                    ht = value;
                    TTC = ht * (1.0 + taux);
                }
            }
        }

        private double ttc;

        public double TTC
        {
            get { return ttc; }
            set
            {
                if(ttc != value)
                {
                    ttc = value;
                    HT = ttc / (1.0 + taux);
                }
            }
        }

    }

tu saisies l'un ça saisie l'autre qui veut ressaisir le premier mais comme c'est la même valeur ça s'arrête là. On n'est pas à l'abris d'un effet de bord du à l'impression des doubles mais bon.

Maintenant le rôle de l'interface est "juste" d'afficher les données connues et de transmettre les données saisies par l'utilisateur. C'est le binding qui va faire le lien entre les objets et l'interface.
Cependant le binding a besoin d'être prévenu quand une donnée est mise à jour.
On va donc implémenter l'ineterface INotifyPropertyChanged, qui comme son non l'indique signale qu'une propriété a été modifiée.

using System.ComponentModel;
namespace exemple
{
    public class Prix : INotifyPropertyChanged
    {
        private double taux = 0.2;

        private double ht;

        public double HT
        {
            get { return ht; }
            set
            {
                if (ht != value)
                {
                    ht = value;
                    GenerePropertyChanged("HT");//demande à signaler le chanagement de valeur de HT
                    TTC = ht * (1.0 + taux);
                }
            }
        }

        private double ttc;

        public double TTC
        {
            get { return ttc; }
            set
            {
                if(ttc != value)
                {
                    ttc = value;
                    GenerePropertyChanged("TTC");
                    HT = ttc / (1.0 + taux);
                }
            }
        }

        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Génère l'évènement attendu par le binding, avec le nom de la propriété
        /// </summary>
        /// <param name="Propriete"></param>
        private void GenerePropertyChanged(string Propriete)
        {
            if (this.PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(Propriete));
        }

        #endregion
    }
}



Maintenant, supposons que tu n'as qu'un prix, et 2 textbox (ta demande quoi), tu ajoutes un objet bindingSource à ton formulaire, dans les propriétés du bindingSource tu vas lui dire qu'il travaille avec une classe Prix (selon la version de VS, il faudra peut-être générer la solution avant cette étape)



Ensuite pour chaque textbox tu vas dire à quelle propriété s'attacher



Bon là tu peux me rétorquer, ça fait beaucoup de trucs à faire pour 2 textbox.
Oui mais:
  • chacun son job, la classe Prix calcule un prix et l'interface sert d'interface,
  • si la "loi" de calcul change, tu ne vas pas trifouiller dans l'interface,
  • si un jour winform n'est plus supporté ou qu'on te demande une version 100% consol, ton code métier est réutilisable tel quel,
  • tu n'as pas géré les conversions double vers string et string vers double
  • si tu as un collection de prix tu peux attacher la collection entière à une listbox ou un datagridview, et l'instance sélectionnée vers les textbox
  • si un jour tu passes à WPF, le binding est quasi obligatoire, c'est la base de cette technologie, commencer à l'apprivoiser en Winform est un atout


Plus d'infos ici
https://codes-sources.commentcamarche.net/faq/1291-utilisation-du-binding-au-travers-de-l-objet-databindingsource


Commenter la réponse de Whismeril
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
0
Merci
Ok, merci NHenry.
Avec mes 6 textbox, ça tourne en boucle et j'ai droit à un "System.StackOverflowException".
Je crois comprendre le problème mais n'arrive pas à le corriger.
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text =="")
            {
                textBox1.Text = "0";
            }

            int a1 = Convert.ToInt32(textBox1.Text);

            
            textBox2.Text = a1.ToString(); 
            textBox3.Text = (a1 * 20).ToString(); 
            textBox4.Text = (a1 * 10).ToString(); 
            textBox5.Text = (a1 * 20).ToString(); 
            textBox6.Text = (a1 * 30).ToString(); 
            

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (textBox2.Text == "")
            {
                textBox2.Text = "0";
            }
            int a2 = Convert.ToInt32(textBox2.Text);

            textBox1.Text = a2.ToString(); 
            
            textBox3.Text = (a2 * 20).ToString(); 
            textBox4.Text = (a2 * 10).ToString(); 
            textBox5.Text = (a2 * 20).ToString(); 
            textBox6.Text = (a2 * 30).ToString(); 
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            if (textBox3.Text == "")
            {
                textBox3.Text = "0";
            }
            int a3 = Convert.ToInt32(textBox3.Text);

            textBox1.Text = (a3 / 20).ToString(); 
            textBox2.Text = (a3 / 20).ToString(); 
            
            textBox4.Text = (a3 / 2).ToString(); 
            textBox5.Text = a3.ToString(); 
            textBox6.Text = (a3 * 3 / 2).ToString(); 
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {
            if (textBox4.Text == "")
            {
                textBox4.Text = "0";
            }

            int a4 = Convert.ToInt32(textBox4.Text);

            textBox1.Text = (a4 / 10).ToString(); 
            textBox2.Text = (a4 / 10).ToString(); 
            textBox3.Text = (a4 * 2).ToString(); 
             
            textBox5.Text = (a4 * 2).ToString(); 
            textBox6.Text = (a4 * 3).ToString(); 
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            if (textBox5.Text == "")
            {
                textBox5.Text = "0";
            }

            int a5 = Convert.ToInt32(textBox5.Text);

            textBox1.Text = (a5 / 20).ToString(); 
            textBox2.Text = (a5 / 20).ToString(); 
            textBox3.Text = a5.ToString(); 
            textBox4.Text = (a5 / 2).ToString(); 
             
            textBox6.Text = (a5 * 3 / 2).ToString(); 
        }

        private void textBox6_TextChanged(object sender, EventArgs e)
        {
            if (textBox6.Text == "")
            {
                textBox6.Text = "0";
            }

            int a6 = Convert.ToInt32(textBox6.Text);

            textBox1.Text = (a6 / 30).ToString(); 
            textBox2.Text = (a6 / 30).ToString(); 
            textBox3.Text = (a6 * 3 / 2).ToString(); 
            textBox4.Text = (a6 / 30).ToString(); 
            textBox6.Text = (a6 * 2).ToString(); 
            
        }
NHenry
Messages postés
14423
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 avril 2019
155 -
if (textBox2.Text.Equals(NewValue)) return;
textBox2.Text=NewValue;

Comme ça si la valeur ne change pas, ça stoppe.
babaOrhumette
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
-
Merci pour cet indice, j'avais pensé à peu près à la même chose sans succès.
Je l'ai placé ici mais j'ai la même erreur.

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (textBox1.Text =="")
            {
                textBox1.Text = "0";
            }

            int a1 = Convert.ToInt32(textBox1.Text);

            if (textBox2.Text.Equals(a1.ToString())) return;
            textBox2.Text = a1.ToString(); 
            textBox3.Text = (a1 * 20).ToString(); 
            textBox4.Text = (a1 * 10).ToString(); 
            textBox5.Text = (a1 * 20).ToString(); 
            textBox6.Text = (a1 * 30).ToString(); 
            

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (textBox2.Text == "")
            {
                textBox2.Text = "0";
            }
            int a2 = Convert.ToInt32(textBox2.Text);

            textBox1.Text = a2.ToString(); 
            
            textBox3.Text = (a2 * 20).ToString(); 
            textBox4.Text = (a2 * 10).ToString(); 
            textBox5.Text = (a2 * 20).ToString(); 
            textBox6.Text = (a2 * 30).ToString(); 
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {
            if (textBox3.Text == "")
            {
                textBox3.Text = "0";
            }
            int a3 = Convert.ToInt32(textBox3.Text);

            textBox1.Text = (a3 / 20).ToString(); 
            textBox2.Text = (a3 / 20).ToString(); 
            
            textBox4.Text = (a3 / 2).ToString(); 
            textBox5.Text = a3.ToString(); 
            textBox6.Text = (a3 * 3 / 2).ToString(); 
        }

        private void textBox4_TextChanged(object sender, EventArgs e)
        {
            if (textBox4.Text == "")
            {
                textBox4.Text = "0";
            }

            int a4 = Convert.ToInt32(textBox4.Text);

            textBox1.Text = (a4 / 10).ToString(); 
            textBox2.Text = (a4 / 10).ToString(); 
            textBox3.Text = (a4 * 2).ToString(); 
             
            textBox5.Text = (a4 * 2).ToString(); 
            textBox6.Text = (a4 * 3).ToString(); 
        }

        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            if (textBox5.Text == "")
            {
                textBox5.Text = "0";
            }

            int a5 = Convert.ToInt32(textBox5.Text);

            textBox1.Text = (a5 / 20).ToString(); 
            textBox2.Text = (a5 / 20).ToString(); 
            textBox3.Text = a5.ToString(); 
            textBox4.Text = (a5 / 2).ToString(); 
             
            textBox6.Text = (a5 * 3 / 2).ToString(); 
        }

        private void textBox6_TextChanged(object sender, EventArgs e)
        {
            if (textBox6.Text == "")
            {
                textBox6.Text = "0";
            }

            int a6 = Convert.ToInt32(textBox6.Text);

            textBox1.Text = (a6 / 30).ToString(); 
            textBox2.Text = (a6 / 30).ToString(); 
            textBox3.Text = (a6 * 3 / 2).ToString(); 
            textBox4.Text = (a6 / 30).ToString(); 
            textBox6.Text = (a6 * 2).ToString(); 
            
        }




Je pense que j'ai trop travaillé dessus aujourd'hui pour y voir bien clair.
NHenry
Messages postés
14423
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
18 avril 2019
155 -
Il faut le faire dans toutes les TextBox, sinon, ce sont les autres qui bouclent.
babaOrhumette
Messages postés
104
Date d'inscription
mardi 14 avril 2009
Statut
Membre
Dernière intervention
7 avril 2019
-
Parfait. Merci encore.
Commenter la réponse de babaOrhumette

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.