Passage d'une Form en paramètre à une fonction

Résolu
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 - 31 août 2017 à 18:59
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 - 1 sept. 2017 à 21:24
Bonjour,

Je cherche à passer un objet Form à une fonction pour effectuer des opérations sur ses propriétés. Je n'arrive pas à trouver le type à déclarer comme paramètre.

Un exemple très simple :
public void GetDimensions(typeinconnu MaForm)
{
    Console.WriteLine("Titre : " + MaForm.Text);
    Console.WriteLine("Hauteur : " + MaForm.Height);
    Console.WriteLine("Largeur : " + MaForm.Width);
}

et quelque part dans le code de la même appli (mais pas forcément dans la même classe), quelque chose comme:
GetDimensions(this)


Par quoi peut-on remplacer "typeinconnu" ?

J'ai trouvé après quelques recherches le moyen de faire cette opération avec un contrôle de la form (par exemple, pour un bouton, le type est ButtonBase).

Mais je n'ai rien trouvé pour une Form : Pas de FormBase ou autre pour désigner une form.

Je précise qu'en plus il est nécessaire que dans ce type de fonction je puisse aussi écrire les propriétés de la Form passée en paramètre

Une idée (validée de préférence) ?

4 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
Modifié le 31 août 2017 à 19:39
Bonjour
Utilise le type
Form



public void GetDimensions(Form MaForm)
{
Console.WriteLine("Titre : " + MaForm.Text);
Console.WriteLine("Hauteur : " + MaForm.Height);
Console.WriteLine("Largeur : " + MaForm.Width);
MaForm.Width = MaForm.Width + 100;
}


La dernière ligne est pour vérifier que la proprièté a bien été modifiée

La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. 
0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
1 sept. 2017 à 11:35
Bonjour,
Merci de la réponse. Ça m'a permis d'avancer, mais non sans mal...

Quand j'écrivais le code avec le type "Form", le compilateur soulignaitGetDimensions en rouge et m'affichait l'erreur :
"Un espace de nom ne peut pas contenir directement des membres tels que des champs ou des méthodes".
Et ça ne venait pas d'un problème de nom de fonction, je l'ai modifié plusieurs fois sans amélioration.

Après plusieurs essais, j'ai créé une classe "machin" dans un nouvel espace de noms "toto" et y ai placé la fonction. L'erreur a disparu. Mais ensuite je n'arrivais pas à appeler la fonction, même en préfixant par l'espace de noms et le nom de la classe.
Dans le code de ma classe principale (une Form), Intellisense me proposait bien toto, puis toto.machin, mais lorsque je tapais le point suivant, seuls "Equals" et "RefrenceEquals" étaient proposés. Et si j'insistais en tapant
toto.machin.GetDimensions(this)
, le compilateur soulignait l'espace et le nom de la fonction en rouge et me répondait :
"Une référence d'objet est requise pour la propriété, la méthode ou le champ non statique 'machin.GetDimensions(Form'"
Manifestement, le this ne lui plaisait pas, mais je ne voyais pas quoi mettre d'autre.

J'ai ensuite tenté de mettre "ref" dans Form dans la fonction pour passer le paramètre par référence : pas d'erreur au niveau de la fonction, mais dans l'appel, le nom de la fonction n'était plus en touge mais cette fois c'est this qui était en rouge avec le message "L'argument doit être passé avec le mot-clé "ref". Ça, d'accord, c'est normal.
Mais lorsque je le faisais, this restait en rouge et l’erreur devienait "Impossible de passer 'this' comme argument ref car il est en lecteur seule".

Enfin, j'ai eu l'idée de retirer les ref et de passer ma classe et ma fonction en static. Plus d'erreur ! Et en plus maintenant Intellisense me propose bien le nom de la fonction. Et à l'essai ça marche !

Merci de m'avoir fourni le bout du fil qu'il m'a fallu dérouler pour arriver à la solution.
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
1 sept. 2017 à 13:28
Bonjour,

ce n'est pas Form qu'il faut mettre, mais le nom de ta Form (Form1 par exemple), car contrairement à VB6 ou une form existe partout, en C# c'est un objet comme un autre, il faut l'instancier (par un new) et c'est l'instance du type de Form1 que tu transmets.

Si tu mets Form, qui est la classe mère, pour accéder aux membres spécifiques de Form1, il faut caster.

Après, il est peu recommandé de passer des Form en paramètre, car ce n'est pas vraiment fidèle au principe MVC, c'est au contrôleur de fournir aux vues (les Form) les données et évènements utiles à l'affichage.

0
MGD Software Messages postés 186 Date d'inscription vendredi 1 septembre 2006 Statut Membre Dernière intervention 23 avril 2022 2
1 sept. 2017 à 15:13
Mais non, ça marche très bien comme ça et ça fait exactement ce que je voulais faire.

Il n'y a rien à caster, l'appel de la fonction passe un this qui est justement une instance de Form (
class wMain : Form
), et dans la fonction appelée, j'ai accès sans problème aux propriétés de cette instance et pas aux autres.

J'ai besoin de ce type de fonction pour sauvegarder et restaurer certains paramètres de mes fenêtres, et je ne souhaite pas me les palucher dans chaque classe.

J'ai l'habitude de créer et d'utiliser du code réutilisable, et il faut parfois que je passe les objets en paramètre aux fonctions d'une classe de ma librairie pour qu'elles œuvrent comme je le souhaite.
0
Whismeril Messages postés 19028 Date d'inscription mardi 11 mars 2003 Statut Non membre Dernière intervention 24 avril 2024 656
1 sept. 2017 à 21:24
Je réalise que j'avais mal compris ton message 2, et qu'au final ta question initiale manquait de contexte.

Quand tu demandes par quoi je remplace typeInconnu, la réponse est Form, Form1, wMain comme tu le montres dans ton message 4.
Si tu mets Form, tu auras accès sans caster aux champ de la classe Form, comme ton exemple était Text, Height et Width, c'est correct.
Mais si tu veux accéder à un TextBox, un bouton ou une nouvelle propriété de wMain, il faut soir mettre le type wMain soit avoir le type Form et ensuite caster.

Mais ton problème au final n'était pas là.
Une référence d'objet est requise pour la propriété, la méthode ou le champ non statique 'machin.GetDimensions

Ne veut par dire que tu as un problème de type, mais que tu n'as pas instancié machin, tu n'as pas fait
machin toto = new machin();
et en même temps, la méthode GetDimensions n'est pas une méthode static, en français méthode de classe, c'est à dire attachée à la classe et non à une instance.

Ton problème d'aujourd'hui et le même que celui d'hier, tu ne peux pas appeler une méthode qui tombe du ciel.
Il te faut un objet instancié ou rendre la méthode static.

Et que tu mettes ref n'a fait,que masquer le problème initial.
D'ailleurs ce modificateur ne sert à rien, en effet à part les types de bases (int, double, char, byte, etc...) tous les autres types sont des références.
0
Rejoignez-nous