Ajout de boutons par programme - Problème avec la souscription à un événement de souris
-
05-07-2019 - |
Question
J'ajoute une liste de boutons dans le code et je m'abonne également à leur événement Mouseleave. Pour chaque bouton que je souscris à l'événement avec une fonction anonyme, le problème est que lorsque je lance l'application, ils sont tous abonnés à la dernière fonction anonyme. Voici le code, j'espère m'être expliqué.
var modules = ModulesSC.GetAllMoudules();
var imageSet = ModulesSC.GetModuleImageSet();
foreach (var module in modules)
{
var btn = new Button();
btn.SetResourceReference(Control.TemplateProperty, "SideMenuButton");
btn.Content = module.Title;
btn.MouseEnter += (s, e) => { ShowInfo(module.Description); };
btn.MouseLeave += (s, e) => { HideInfo(); };
ModuleButtons.Children.Add(btn);
}
protected void HideInfo()
{
DescriptionLabel.Visibility = Visibility.Collapsed;
DescriptionText.Text = string.Empty;
}
protected void ShowInfo(string description)
{
DescriptionLabel.Visibility = Visibility.Visible;
DescriptionText.Text = description;
}
Quand je lance l'application, ils appellent tous showInfo avec le dernier "module.Description"
.Merci -Alejandro
La solution
C’est un problème avec la façon dont C # ferme les variables de boucle. Ajoutez une variable temporaire dans et utilisez-la dans votre méthode anonyme:
foreach (var module in modules)
{
var theModule = module; // local variable
var btn = new Button();
btn.SetResourceReference(Control.TemplateProperty, "SideMenuButton");
btn.Content = theModule.Title; // *** use local variable
btn.MouseEnter += (s, e) => { ShowInfo(theModule.Description); }; // *** use local variable
btn.MouseLeave += (s, e) => { HideInfo(); };
ModuleButtons.Children.Add(btn);
}
Notez l’utilisation de la variable locale "theModule". au lieu de la variable de boucle "module".
Autres conseils
Je ne sais pas de quelle langue il s'agit, mais il pourrait s'agir de C #.
Si tel est le cas, les gestionnaires d'événements de clic sur le bouton doivent avoir un "expéditeur d'objet". et un argument EventArgs à la fonction.
Le " objet expéditeur " peut vous dire quel bouton a été appuyé.
Button pressedButton = (Button)sender;
if(pressedButton.Text.Equals("Button 1")
doStuff();
Ce n'est qu'un exemple. Il existe de meilleurs moyens de déterminer de quel bouton il s'agit plutôt que de comparer le champ de texte, mais vous avez l'idée.