MGD Software
Messages postés188Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention 4 juillet 2024
-
Modifié le 9 août 2019 à 14:54
Whismeril
Messages postés19147Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 3 octobre 2024
-
14 août 2019 à 12:08
Bonjour,
En VB6, j'avais l'habitude, pour synchroniser plusieurs fenêtre filles MDI, d'appeler dans un boucle une procédure dont le nom était commun à toutes les feuilles. Genre :
For Each F In Forms
If Not F Is wMain Then F.UpdateAll
Next
Je précise que bien sûr ces feuilles sont différentes (sinon ce serait très simple), mais chacune présente une procédure publique nommée UpdateAll.
En C#, cela donnerait ceci, qui bien sûr ne fonctionne pas.
foreach (Form F in Application.OpenForms)
if (!F.GetType().Equals(typeof(wMain)))
F.UpdateAll();
En C#, il est normal que cela ne convienne pas au compilateur, car la procédure UpdateAll n'est pas reconnue pour la classe Form.
Je suppose qu'il faudrait une interface commune, mais je ne sais pas encore faire ça.
Une extension de la classe Form ?
Une implémentation d'interface ?
Une interception de la méthode Update() de Form ?
Ou autre chose...
Ecrire une interface est assez simple.
C’est comme écrire une classe abstraite, sauf que le corps des méthodes est toujours vide.
Le paragraphe du cours de Tahé est assez explicite je pense
https://tahe.developpez.com/dotnet/csharp/?page=page_5#LV-F
Une autre option est d’abonner tes forms à un événement.
Au lieu d’appliquer ta méthode dans une boucle , tu déclenches l’événement et les forms concernées vont y réagir.
MGD Software
Messages postés188Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention 4 juillet 20242 9 août 2019 à 19:12
Ok pour le 'As'. Je connaissais déjà, grâce à toi dans un post datant de mes débuts en C# (à peine un an !).
Je connaissait 'Is' en VB6, pas en C#. Cependant hélas cela ne marche à priori que pour des types, pas pour des objets. En effet, si j'écris :
foreach(Form F in this.MdiChildren)
if(F is wMachin)
...
Le compilateur ne génère pas d'erreur. Je suppose que si plusieurs instances de wMachin sont ouvertes, elles seront toutes concernées.
Par contre, si j'écris :
foreach(Control Ctrl in this.Controls)
if(Ctrl is txtNom)
....
le compilateur m'annonce : "Une valeur de constante est attendue". Je dois donc passer par
if Ctrl.Equals(txtNom)
. A moins qu'il n'y ait une autre subtilité ??
J'avais pratiqué le polymorphisme et l'implémentation d'interface en VB6. Le concept ne m'est donc pas inconnu. J'ai jeté un œil sur le cours de Tahé, mais la première lecture n'est pas du tout concluante. Je n'ai pas trouvé la notion d'interface, mais celle de polymorphisme.
Je n'arrive pas à comprendre comment créer une interface et la relier à ma Form.
Pas de problème lorsqu'il s'agit de classes que l'on crée. Par contre, mes feuilles héritent de Form. Comment créer une méthode supplémentaire à la classe Form ?
Ou alors, créer une classe abstraite dérivant de Form, y créer une méthode virtuelle UpdateAll, et dériver mes feuilles de cette classe ? Je ne suis pas sûr que l'IDE de Visual Studio apprécie et me présente correctement l'aspect de ma feuille en mode création.
Tout ça demande encore pas mal de réflexion...
Je reviendrai... (comme Darkvador ;-) )
Whismeril
Messages postés19147Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 3 octobre 2024660 9 août 2019 à 19:17
Non, je reviendrai c’est Terminator ;)
Whismeril
Messages postés19147Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 3 octobre 2024660 Modifié le 9 août 2019 à 19:25
Oui is fonctionne pour un type, une interface, mais pour une constante aussi.
Pour tester si toto est txtNom, il suffit de
if(toto == txtNom)
Pour l’interface, c’est un truc dans ce genre (je suis avec ma tablette, donc je ne peux pas tester)
public interface Imgd
{
public void UpdateAll();
}
Et pour formBidule qui doit implémenter cette interface
public formBidule: Form, Imgd
Et dans le corps de formBidule, tu écris updateAll()
MGD Software
Messages postés188Date d'inscriptionvendredi 1 septembre 2006StatutMembreDernière intervention 4 juillet 20242 14 août 2019 à 09:15
Bonjour Whismeril,
Il doit me manquer une info...
J'ai bien déclaré une interface IUpdatable :
public interface IUpdatable
{
void UpdateForm();
}
Dans mes feuilles, j'ai ajouté à la déclaration de classe la référence à IUpdatable :
public class MyForm : Form, IUpdatable
Dans la classe, j'ai placé une procédure
public void UpdateForm()
{
...
}
Mais quand je mets dans ma feuille MDI principale les lignes :
public void UpdateAll()
{
foreach (Form F in MdiChildren)
F.UpdateForm();
}
Le compilateur ne reconnait pas la méthode UpdateForm. Je suppose que c'est normal, car il ne sait pas que F dispose de l'interface IUpdatable.
Je suppose qu'il faut ajouter ou modifier la déclaration de F dans la boucle. J'ai tenté de remplacer Form par IUpdatable dans le foreach, mais cela ne marche pas : F.UpdateForm() ne provoque plus d'erreur, mais IUpdatable provoque une erreur "Type introuvable" Je précise que la déclaration de l'interface est bien située dans l'espace de nom commun à toutes les fenêtres.
Un conseil ?
PS : Pendant que j'écrivais, j'ai trouvé :
foreach (Form F in MdiChildren)
((IUpdatable)F).UpdateForm();
Bon sang, mais c'est bien sûr !
Je manque encore de réflexes C#...
Whismeril
Messages postés19147Date d'inscriptionmardi 11 mars 2003StatutContributeurDernière intervention 3 octobre 2024660 14 août 2019 à 12:08