Botones para agregar mediante programación - Problema con la suscripción a un evento del mouse

StackOverflow https://stackoverflow.com/questions/1806005

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

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top