Passing variable argument in a loop to eventhandler

zequion 401 Reputation points
2024-09-05T01:52:24.05+00:00

In WPF I have a Styles button in which I add items with the different styles:

<Button x:Name="Form_Estilos">
    <Button.ContextMenu>
        <ContextMenu x:Name="Form_Estilos_Items"/>
    <ItemsControl>
        <Image x:Name="Form_Estilos_Image" Source="{StaticResource estilos}">
    </ItemsControl>
</Button>

By code I add the style names to the Items in "Form_Styles_Items". Then, I have a loop to add the Click and MouseEnter events to each of the Items:

int index = 0;
foreach(System.Windows.Controls.MenuItem Item_ in Estilo_Control_.Items)
{       index++;
        Item_.AddHandler(System.Windows.Controls.MenuItem.ClickEvent,      new System.Windows.RoutedEventHandler((sender, e) => Fcn_Menu_Estilo_ButtonItem_Apoyo(sender, e, index)));
        Item_.AddHandler(System.Windows.Controls.MenuItem.MouseEnterEvent, new System.Windows.RoutedEventHandler((sender, e) => Fcn_Menu_Estilo_ButtonItem_Apoyo(sender, e, index + 1)));
} 

public static void Fcn_Menu_Estilo_ButtonItem_Apoyo(System.Object sender, System.Windows.RoutedEventArgs e, int index)
 {       if (MainForm == null) return;

         switch(index)
         {   case 1:   MainForm.Fcn_Menu_Estilo_Tema_ButtonItem_Evento(sender, e, Name_Estandar_Eventos_Central.Informacion.EstiloSup_ButtonItem_Click); break;
             case 2:   MainForm.Fcn_Menu_Estilo_Tema_ButtonItem_Evento(sender, e, Name_Estandar_Eventos_Central.Informacion.EstiloSup_ButtonItem_MouseEnter); break;
         }
 }

The problem is that when you Click or MouseEnter on any item, the index value in Fcn_Menu_Estilo_ButtonItem_Apoyo() is always the last index.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,762 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,858 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hui Liu-MSFT 48,506 Reputation points Microsoft Vendor
    2024-09-05T03:27:12.68+00:00

    Hi,@zequion.Welcome to Microsoft Q&A. To dynamically add event handlers to items in a context menu in WPF and pass index parameters to these handlers, you could refer to the following sample code, which creates a context menu, adds items to it, and assigns event handlers with the correct index passed dynamically.

     <Grid >
         <Button x:Name="Form_Estilos" Content="Styles Button" Width="200" Height="50">
             <Button.ContextMenu>
                 <ContextMenu x:Name="Form_Estilos_Items"/>
                 </Button.ContextMenu>
         </Button>
     </Grid>
    

    In the C# code-behind, you'll programmatically add MenuItems to the ContextMenu, then loop through those items to attach event handlers for Click and MouseEnter, passing the index to the event handler .

     public partial class MainWindow : Window
     {
         public MainWindow()
         {
             InitializeComponent();
             AddMenuItemsToContextMenu();
         }
         private void AddMenuItemsToContextMenu()
         {
             Form_Estilos_Items.Items.Clear();
             for (int i = 0; i < 5; i++)
             {
                 MenuItem menuItem = new MenuItem();
                 menuItem.Header = $"Style {i + 1}";
                 int index = i; 
                 menuItem.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler((sender, e) => Fcn_Menu_Estilo_ButtonItem_Apoyo(sender, e, index)));
                 menuItem.AddHandler(MenuItem.MouseEnterEvent, new RoutedEventHandler((sender, e) => Fcn_Menu_Estilo_ButtonItem_Apoyo(sender, e, index + 1)));
    
                 Form_Estilos_Items.Items.Add(menuItem);
             }
         }
       
         public static void Fcn_Menu_Estilo_ButtonItem_Apoyo(object sender, RoutedEventArgs e, int index)
         {
             MessageBox.Show($"Event fired for Style {index }", "Event Handler", MessageBoxButton.OK, MessageBoxImage.Information);
    
            
         }
    

    You can customize how index is calculated or passed to the handler. Replace the MessageBox.Show with your actual event handling logic.

    If the problem persists, you could share more complete sample code that reproduces the issue.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.