Utilisation générique de controles updown [Résolu]

Messages postés
169
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
24 septembre 2019
-
Bonjour,

J'ai un petit souci pour récupérer la valeur d'un contrôle NumericUpDown dans une boucle générique.
Afin de sauvegarder mon contexte, j'utilise une fonction qui me ramène la liste de tous les contrôles de la feuille :
/// <summary>
///  Liste de tous les controles contenus dans un conteneur, y compris dans les conteneurs enfants
/// </summary>
/// <param name="Parent">Conteneur de départ</param>
/// <returns>Un objet List contenant les controles</returns>
public static  List<Control> GetChildren(Control Parent)
{
    List<Control> ControlList = new List<Control>();
    GetChildren(Parent, ControlList);
    return ControlList;
}
private static void GetChildren(Control Parent, List<Control> ControlList = null)
{
    foreach (Control Ctrl in Parent.Controls)
        if (Ctrl.HasChildren)
            GetChildren(Ctrl, ControlList);
        else
            ControlList.Add(Ctrl);
}

Avec cette liste, je sauve à la fermeture et je recharge au démarrage avec une fonction du genre :
foreach(Control Ctrl in MgdDiv.GetChildren(this))
{
    if (Ctrl.GetType().Equals(typeof(TextBox)))
        ParamSave(Ctrl.Name, Ctrl.Text);
    else if (Ctrl.GetType().Equals(typeof(RadioButton)))
        ParamSave(Ctrl.Name, ((RadioButton)Ctrl).Checked);
}

Jusqu'à présent tout allait bien jusqu'à ce que j'ajoute les lignes :
else if (Ctrl.GetType().Name == "UpDownButtons")
    ParamSave(Ctrl.Name, ((NumericUpDown)Ctrl).Value);

Déjà, le filtre du If n'est pas conforme au reste. Mais si je mets
if (Ctrl.GetType().Equals(typeof(NumericUpDown)))
, on ne passe jamais dans la ligne suivante. Il semble que mes UpDown n'aient pas ce type. Pourtant, si je mets un point d'arrêt et tape dans la fenêtre de débogage "Ctrl.GetType().Name", cela répond "UpDownButtons".

Plus bizarre : Si je tape GetChildren(this) dans la fenêtre de débogage, j'obtiens la liste suivante (tronquée pour ne faire trop long) :
   [0]: {System.Windows.Forms.ListView, Items.Count: 0}
    [1]: {Text = "y"}
    [2]: {System.Windows.Forms.Label, Text: Chaîne de remplacement :}
    [3]: {Text = "x"}
    [6]: {System.Windows.Forms.UpDownBase+UpDownButtons}
    [7]: {Text = "0"}
    [8]: {System.Windows.Forms.UpDownBase+UpDownButtons}
    [9]: {Text = "0"}
    [10]: {Text = ""}
  

A priori, les indices 6 et 8 sont deux de mes updown.
Il semble que ce soit une surcharge de la classe UpDownBase. Mais si je teste ce type de classe, cela ne fonctionne pas non plus.

J'ai donc opté pour une solution beaucoup moins propre : tester le nom du type du contrôle. J'ai donc mis dans le test :
if (Ctrl.GetType().Name == "UpDownButtons")

Ça, ça marche, bien que ça me défrise quelque peu.

Mais alors, le problème suivant survient : toutes mes tentatives pour récupérer la valeur du contrôle échouent.
((NumericUpDown)Ctrl).Value => Exception (cast non valide)
((UpDownBase)Ctrl).Value => UpDownBase ne possède pas de propriété Value
Ctrl.Value => Idem (normal, mais à tout hasard...)

Autre anomalie : Ctrl.Name ramène une chaîne vide !
Pourtant je suis sûr d'être sur un de mes UpDown, et l'application fonctionne. Je ne pense pas que le C# accepte des contrôles sans nom. J'ai essayé, et j'ai eu une message d'erreur.

Alors comment faire pour récupérer la valeur d'un UpdDown sans le nommer explicitement, ou quand on le récupère sous forme d'objet générique ???
Afficher la suite 

2 réponses

Messages postés
169
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
24 septembre 2019
0
Merci
De mieux en mieux : J'ai mis dans ma boucle la ligne :
Console.WriteLine("{0} : {1}", Ctrl.Name, Ctrl.GetType().Name);


Et voilà ce que ça sort :
lvwListe : ListView
txtReplaceMask : TextBox
label2 : Label
txtFilterMask : TextBox
label3 : Label
label1 : Label
: UpDownButtons
: UpDownEdit
: UpDownButtons
: UpDownEdit
txtInsText : TextBox
optInsSupLocBefore : RadioButton
optInsSupLocAfter : RadioButton
lblSupprNbCar : Label
lblInsText : Label
lblInsSupLocSuffix : Label
lblInsSupLocPrefix : Label
optInsSupSelDel : RadioButton
optInsSupSelIns : RadioButton
txtRenumStart : TextBox
: UpDownButtons
: UpDownEdit
: UpDownButtons
: UpDownEdit
: UpDownButtons
: UpDownEdit
: UpDownButtons
: UpDownEdit
label8 : Label
label11 : Label
label10 : Label
label9 : Label
label5 : Label
btnItemMoveDown : Button
btnItemMoveUp : Button
label12 : Label
optRenumTypeLetter : RadioButton
optRenumTypeNum : RadioButton
optRenumLocBefore : RadioButton
optRenumLocAfter : RadioButton
picWarning : PictureBox
label15 : Label
: UpDownButtons
: UpDownEdit
label16 : Label
label14 : Label
optModifExtIni : RadioButton
optModifExtMaj : RadioButton
optModifExtMin : RadioButton
optModifExtNone : RadioButton
optModifNameIni : RadioButton
optModifNamesMaj : RadioButton
optModifNameMin : RadioButton
optModifNameNone : RadioButton
tbrTools : ToolStrip
mnuMenus : MenuStrip


Pas de trace de NumericUpDown !
Par contre, j'ai des UpDownButtons et des UpDownEdit sans nom !!
Je suppose que les UpDown sont des objets composés d'une zone de texte et d'une tournette, comme on faisait avec VB6. Mais comment les adresser de façon générique, et comment récupérer la valeur de la partie "Edit" ?

PS : Je rappelle que la console ne sort toujours pas dans la fenêtre Sortie, et je dois passer l'appli en application console pour obtenir une sortie dans une fenêtre type DOS - Voir mon sujet précédent : https://codes-sources.commentcamarche.net/forum/affich-10093912-windows-forms-console-write-ne-sort-plus-dans-la-fenetre-de-sortie#p10094008
Commenter la réponse de MGD Software
Messages postés
169
Date d'inscription
vendredi 1 septembre 2006
Statut
Membre
Dernière intervention
24 septembre 2019
0
Merci
J'ai trouvé !!

Ma fonction de listage ne renvoyait pas les objets ayant des enfants, mais seulement les objets sans enfants, et les enfants des objets avec enfants (donc au final QUE des objets sans enfants).
Or contrairement aux autres contrôles communs, il semble que le contrôle NumericUpDown ait des enfants.

En modifiant ma fonction récursive ainsi :
private static void GetChildren(Control Parent, List<Control> ControlList = null)
{
    foreach (Control Ctrl in Parent.Controls)
    {
        ControlList.Add(Ctrl);
        if (Ctrl.HasChildren)
            GetChildren(Ctrl, ControlList);
    }                    
}

J'obtiens dans la liste :
.....
updRenumLoc : NumericUpDown
: UpDownButtons
: UpDownEdit
updRenumStart : NumericUpDown
: UpDownButtons
: UpDownEdit
updRenumInc : NumericUpDown
: UpDownButtons
: UpDownEdit
updRenumFmt : NumericUpDown
: UpDownButtons
: UpDownEdit
.....


Et je peux avoir les valeurs avec
if (Ctrl.GetType().Equals(typeof(NumericUpDown)))
    ParamsSave(Ctrl.Name, ((NumericUpDown)Ctrl).Value)


Beaucoup de bruit pour rien, désolé.
Mais si ça peut servir à quelqu'un...
Commenter la réponse de MGD Software