none
J'aimerais comprendre... RRS feed

  • Question

  • Bonjour,

    Je suis débutant en C#. Je viens du PHP, mais j'ai jamais codé en objet et j'avoue que je suis un peu perdu. J'ai téléchargé Visual Studio Express 2005 et j'ai fait quelques exercices, notemment une bonne partie du programme Coach, proposé sur msdn.

    Mais j'ai décidé de développer mon propre programme, tout bête, histoire de bien comprendre la mécanique de la POO et du C# par la même occasion.

    Voilà l'idée de base. Développer une application qui permette de calculer, soit le périmètre d'un rectangle, soir sa surface... Super original Smile. J'ai créé un formulaire avec 3 champs textbox, deux boutons. Deux champs pour entrer largeur, longueur. Un bouton pour calculer la surface, un pour le périmètre et le dernier champs text, en read only pour afficher le résultat.

    J'ai créé 2 méthodes, une pour chaque calcul.

    Par contre je n'arrive pas à comprendre, comment récupérer les données saisient dans les champs textbox, les traiter et les retourner au champs résultat.

    J'en vois qui rigolent, mais je débute, je débute Smile

    Voilà le code que j'ai déjà

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;

    namespace Exercice_Calcul
    {
        public partial class Main : Form
        {
            public Main()
            {
                InitializeComponent();
            }

            private void CalculSurface(int Largeur, int Longueur)
            {
                int result = (Largeur * Longueur);
            }

            private void CalculPerimetre(int Largeur, int Longueur)
            {
                int result = ((2 * Largeur) + (2 * Longueur));
            }

            private void calculSurfaceButton_Click(object sender, EventArgs e)
            {

            }
        }
    }

    le EnventArgs pour calculer la surface à été obtenu en double-cliquand sur le bouton... Mais je sais pas quoi mettre dedans... Crying

    Je vous remercie d'avance pour votre aide ^^
    vendredi 14 mars 2008 13:12

Réponses

  • Bonjour,

    Normalement vos TextBox ont chacunes un nom unique (par defaut c'est TextBox1, TextBox2, ...). A partir de ces noms, Visual Studio crée automatiquement des champs dans votre classe pour accéder à ces objets.

    Supposons que vous ayez appeler vos TextBox : txtLargeur, txtLongueur et txtResultat :

     

    Code Snippet

    private void calculSurfaceButton_Click(object sender, EventArgs e)

    {

    // on récupère la largeur, la TextBox renvoyant une chaine, il faut la convertir en entier

    int largeur = 0;

    if (!int.TryParse(this.txtLargeur.Text, out largeur))

    {

    // le texte n'est pas un entier

    return;

    }

     

    // on récupère la longueur

    int longueur = 0;

    if (!int.TryParse(this.txtLongueur.Text, out longueur))

    {

    // le texte n'est pas un entier

    return;

    }

     

    // calcul la surface et l'affiche

    this.txtResultat.Text = this.CalculSurface(largeur, longueur).ToString():

    }

     

     

    Par ailleurs il y a un problème dans votre code, la méthode CalculSurface retourne un int mais sa déclaration déclare void en type de retour.

     

    Guillaume

    vendredi 14 mars 2008 13:22
  •  

    Concernant ta première question, je ne dirai pas que c'est du casting mais du parsing (tryparse )

    En fait le casting serait pluto un truc du genre:

     

    Class Roue{}

     

    Class RoueDeVelo:Roue{} //RoueDeVelohérite de Roue

     

    main()

    {

    Roue a = new RoueDeVelo();

     

    RoueDeVelob = (RoueDeVelo) a;

     

    c'est le fait de "mettre" un a dans le b avec le (RoueDeVelo) qui est l'action de faire le casting. ce n'est possible que parce que le contenu réel de a est bien une RoueDeVelo sinon tu obtiens des erreurs (je te conseille de prendre cet exemple et de le mettre dans un projet console et de jouer avec. Ca te permettras de jouer aussi avec l'opérateur virtual, ovverride, new, ...)

    Pour tes exemples simples, tu as peu de raison d'avoir besoin de faire ce genre de chose. Garde toi ce fun pour après

    Un petit lien msdn sur le casting: http://msdn2.microsoft.com/fr-fr/library/ms173105(VS.80).aspx

     

    Pour ta deuxième partie je dirais oui avec le détail suivant pour expliquer

    quand tu prends

    this.txtResultat.Text = this.CalculSurface(largeur, longueur).ToString();

    Tu veux que CalculSurface(largeur, longueur).ToString(); te retournes une chaine ce qui veux dire que:
    CalculSurface(largeur, longueur) ne retourne pas une chaine. En regardant la méthode on se dit qu'elle devrait retourner un int (une méthode qui prend 2 int et renvoie une opération sur ces int est généralement un résultat en int)

     

    Je commencerais donc par modifier la signature de

     private void CalculSurface(int Largeur, int Longueur) //void voulant dire ne retourne rien en

     private int CalculSurface(int Largeur, int Longueur) //cette méthode va retourner un int

     

    puis il faut modifier le contenu de la méthode pour lui dire de retourner effectivement le résultat (on emploiera le return) ce qui donne:

     private int CalculSurface(int Largeur, int Longueur)

    {
              int result = (Largeur * Longueur);

              return result;

    }

    voire en simplifiant à l'extrème:

     private int CalculSurface(int Largeur, int Longueur)

    {
              return (Largeur * Longueur);

    }

    note: le produit de deux int peux dépasser le contenu d'un int (il faut y penser quand tu commenceras à aller plus loin)


    Bon courage pour la suite et bon fun


    vendredi 14 mars 2008 15:59

Toutes les réponses

  • Bonjour,

    Normalement vos TextBox ont chacunes un nom unique (par defaut c'est TextBox1, TextBox2, ...). A partir de ces noms, Visual Studio crée automatiquement des champs dans votre classe pour accéder à ces objets.

    Supposons que vous ayez appeler vos TextBox : txtLargeur, txtLongueur et txtResultat :

     

    Code Snippet

    private void calculSurfaceButton_Click(object sender, EventArgs e)

    {

    // on récupère la largeur, la TextBox renvoyant une chaine, il faut la convertir en entier

    int largeur = 0;

    if (!int.TryParse(this.txtLargeur.Text, out largeur))

    {

    // le texte n'est pas un entier

    return;

    }

     

    // on récupère la longueur

    int longueur = 0;

    if (!int.TryParse(this.txtLongueur.Text, out longueur))

    {

    // le texte n'est pas un entier

    return;

    }

     

    // calcul la surface et l'affiche

    this.txtResultat.Text = this.CalculSurface(largeur, longueur).ToString():

    }

     

     

    Par ailleurs il y a un problème dans votre code, la méthode CalculSurface retourne un int mais sa déclaration déclare void en type de retour.

     

    Guillaume

    vendredi 14 mars 2008 13:22
  • Merci beaucoup pour ces précisions Smile

    J'aimerais être sûre d'avoir bien compris.

    *****************************
    // on récupère la longueur

    int longueur = 0;

    if (!int.TryParse(this.txtLongueur.Text, out longueur))

    {

        // le texte n'est pas un entier

        return;

    }
    *****************************
    C'est bien ça qu'on appelle du "Casting"???

    *****************************
    // calcul la surface et l'affiche

    this.txtResultat.Text = this.CalculSurface(largeur, longueur).ToString();
    *****************************
    On peut traduire par : (Ce que tu vas calculer) tu le passe à txtResultat à l'attribut Text et c'est égale à (Ce que tu vas calculer) avec la méthode CalculSurface(paramètres) que tu convertis en string.

    C'est bien ça???


    Par contre pour la déclaration de la méthode, je devrais mettre quel type??? J'ai essayé avec String et int, mais j'ai une erreure de compilation... Crying
    vendredi 14 mars 2008 14:23
  •  

    Concernant ta première question, je ne dirai pas que c'est du casting mais du parsing (tryparse )

    En fait le casting serait pluto un truc du genre:

     

    Class Roue{}

     

    Class RoueDeVelo:Roue{} //RoueDeVelohérite de Roue

     

    main()

    {

    Roue a = new RoueDeVelo();

     

    RoueDeVelob = (RoueDeVelo) a;

     

    c'est le fait de "mettre" un a dans le b avec le (RoueDeVelo) qui est l'action de faire le casting. ce n'est possible que parce que le contenu réel de a est bien une RoueDeVelo sinon tu obtiens des erreurs (je te conseille de prendre cet exemple et de le mettre dans un projet console et de jouer avec. Ca te permettras de jouer aussi avec l'opérateur virtual, ovverride, new, ...)

    Pour tes exemples simples, tu as peu de raison d'avoir besoin de faire ce genre de chose. Garde toi ce fun pour après

    Un petit lien msdn sur le casting: http://msdn2.microsoft.com/fr-fr/library/ms173105(VS.80).aspx

     

    Pour ta deuxième partie je dirais oui avec le détail suivant pour expliquer

    quand tu prends

    this.txtResultat.Text = this.CalculSurface(largeur, longueur).ToString();

    Tu veux que CalculSurface(largeur, longueur).ToString(); te retournes une chaine ce qui veux dire que:
    CalculSurface(largeur, longueur) ne retourne pas une chaine. En regardant la méthode on se dit qu'elle devrait retourner un int (une méthode qui prend 2 int et renvoie une opération sur ces int est généralement un résultat en int)

     

    Je commencerais donc par modifier la signature de

     private void CalculSurface(int Largeur, int Longueur) //void voulant dire ne retourne rien en

     private int CalculSurface(int Largeur, int Longueur) //cette méthode va retourner un int

     

    puis il faut modifier le contenu de la méthode pour lui dire de retourner effectivement le résultat (on emploiera le return) ce qui donne:

     private int CalculSurface(int Largeur, int Longueur)

    {
              int result = (Largeur * Longueur);

              return result;

    }

    voire en simplifiant à l'extrème:

     private int CalculSurface(int Largeur, int Longueur)

    {
              return (Largeur * Longueur);

    }

    note: le produit de deux int peux dépasser le contenu d'un int (il faut y penser quand tu commenceras à aller plus loin)


    Bon courage pour la suite et bon fun


    vendredi 14 mars 2008 15:59
  • Un grand merci à vous.

    J'ai réussi à faire mon programme et tout fonctionne correctement.

    J'y vois un peu plus claire, maintenant.

    Merci beaucoup Smile
    lundi 17 mars 2008 06:57
  • Voilà, suivant vos conseils, j'ai modifié mon code pour arriver à ça

    *************************************************************
    namespace Exercice_Calcul
    {
        public partial class Main : Form
        {
            public Main()
            {
                InitializeComponent();
            }

            private decimal ConvertStringToDeci(decimal result)
            {
                //On récupère la largeur, la TextBox renvoyant une chaine, il faut la convertir en entier
                decimal Largeur = 0;
                if (!decimal.TryParse(this.largeurTextBox.Text, out Largeur))
                {
                    //le texte n'est pas un entier
                    return;
                }

                //On récupère la longueur, idem que la largeur
                decimal Longueur = 0;
                if (!decimal.TryParse(this.longueurTextBox.Text, out Longueur))
                {
                    //le texte n'est pas un entier
                    return;
                }
            }
           
            private decimal CalculSurface(decimal Largeur, decimal Longueur)
            {
                return (Largeur * Longueur);
            }

            private decimal CalculPerimetre(decimal Largeur, decimal Longueur)
            {
                return ((2 * Largeur) + (2 * Longueur));
            }

            private void calculSurfaceButton_Click(object sender, EventArgs e)
            {
                //Calcul de la surface
                this.resultatTextBox.Text = this.CalculSurface(this.ConvertStringToDeci(Largeur), this.ConvertStringToDeci(Longueur)).ToString();
            }

            private void calculPerimetreButton_Click(object sender, EventArgs e)
            {
                //Calcul du périmètre
                this.resultatTextBox.Text = this.CalculPerimetre(this.ConvertStringToDeci(Largeur), this.ConvertStringToDeci(Longueur)).ToString();
            }
        }
    }
    *************************************************************

    J'ai transformé la procédure de Tryparse en méthode pour éviter de la réécrire 2x. Le code fonctionne comme ça et est, à mon huble avis, relativement propre... A un détail...

    Chaque fois que j'appelle ma méthode "ConvertStringToDeci" elle fait la convertion pour les 2 champs. Ce qui fait que pour calculer la surface, par exemple, le programme fait 4 convertion au lieu de 2.

    Est-ce que c'est possible de réduide la méthode à 1 tryparse, en fonction du paramètre à convertir???

    D'avance merci.
    lundi 17 mars 2008 15:23
  • Bonjour,

    Voila une fonction "générique" pour la conversion :

     

    Code Snippet

    private decimal ConvertStringToDecimal(string value)

    {

    decimal result = 0;

    if (!decimal.TryParse(value, out result))

    {

    // la chaine n'est pas un decimal, on retourne une valeur bidon

    return -1;

    }

     

    return result;

    }

     

     

    La fonction prend en paramètre une chaine et essaye de la convertir en decimal.

    Puis vous l'appelez comme ceci :

     

    Code Snippet

    private void calculSurfaceButton_Click(object sender, EventArgs e)
    {

    //Calcul de la surface

    this.resultatTextBox.Text = this.CalculSurface(

    this.ConvertStringToDecimal(this.largeurTextBox.Text)

    , this.ConvertStringToDecimal(this.longueurTextBox.Text)

    ).ToString();

    }

     

     

    Il y a aussi plus simple mais vous devrez gérer les exceptions :

     

    Code Snippet

    private void calculSurfaceButton_Click(object sender, EventArgs e)
    {

    try

    {

    //Calcul de la surface

    this.resultatTextBox.Text = this.CalculSurface(

    Convert.ToDecimal(this.largeurTextBox.Text)

    , Convert.ToDecimal(this.longueurTextBox.Text)

    ).ToString();

    }

    catch (FormatException ex)

    {

    // la chaine n'est pas un decimal

    }

    }

     

     

    La classe Convert possède un grand nombre de méthode de conversion (je vous laisse regarder la documentation). Son inconvénient est qu'elle lève une exception si la conversion ne peut pas se faire contrairement au TryParse qui lui renvoi un booléen indiquant s'il a réussi ou non la conversion.

     

    Guillaume


    lundi 17 mars 2008 16:11
  • La variante sans l'objet Convert fonctionne très bien merci Smile

    Vu mon niveau, je ne maitrise pas du tout les exception et je n'ai aucune idée sur la façon de les traiter... Pour le moment Wink

    Merci beaucoup pour votre aide

    mardi 18 mars 2008 06:24