Botones para agregar mediante programación - Problema con la suscripción a un evento del mouse
-
05-07-2019 - |
Pregunta
Estoy agregando una lista de botones en el código y también me estoy suscribiendo a su evento de réplica. Para cada botón que me suscribo al evento con una función anónima, el problema es que cuando ejecuto la aplicación, todos están suscritos a la última función anónima. Aquí está el código, espero que me haya explicado.
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;
}
Cuando ejecuto la aplicación, todos llaman a showInfo con las " module.Description "
Gracias -Alejandro
Solución
Este es un problema con la forma en que C # se cierra sobre las variables de bucle. Agregue una variable temporal dentro y úsela en su método anónimo:
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);
}
Tenga en cuenta el uso de la variable local " theModule " en lugar de la variable de bucle " módulo. "
Otros consejos
No sé qué idioma es este, pero podría ser C #.
Si es así, los controladores de eventos de clic de botón deben tener un " object sender " y un argumento EventArgs a la función.
El " remitente de objeto " puedo decirle qué botón se presionó.
Button pressedButton = (Button)sender;
if(pressedButton.Text.Equals("Button 1")
doStuff();
Eso es solo un ejemplo, hay mejores maneras de determinar qué botón es que comparando el campo de texto, pero entiendes la idea.