Dynamically Adding event handlers to WPF

11,114

Solution 1

You need to define a set of actions that the user will be able to do. Then assign a name to each one of them and implement the actions in code.

For example, the XML would be:

<Button Content="TextOnAddQueryButton" Command="CamlAddQueryLine"></Button>

In code, you would assign the event handler like this:

private void AddButtonToGroup(string header,RibbonGroup group,string command,string action)
{
     RibbonButton button = new RibbonButton();
     button.Tag = command;
     //...
}

And the handler for the button would be:

void button_Click(object sender, RoutedEventArgs e)
{
    Button clicked = (Button)sender;

    switch (clicked.Tag)
    {
        case "CamlAddQueryLine":
            // Call action for CamlAddQueryLine
            break;
    }
}

Solution 2

You could create a method that returns an Action<object, RoutedEventArgs>:

private Action<object, RoutedEventArgs> MakeButtonClickHandler()
{
   return (object sender, RoutedEventArgs e) =>
      {
         // Put your code here, it will be called when
         // the button is clicked
      };
}

So MakeButtonClickHandler returns a new anonymous function each time it's called. Then assign it like this:

button.Click += new RoutedEventHandler(MakeButtonClickHandler());

Another way of accomplishing the same thing is to do this inline, like so:

button.Click += (object sender, RoutedEventArgs e) =>
    {
        // Put your code here
    };

For some more information, take a look at Anonymous Functions on MSDN.

Share:
11,114
scarecrow198504
Author by

scarecrow198504

Updated on June 16, 2022

Comments

  • scarecrow198504
    scarecrow198504 almost 2 years

    I'm looking for help with an app I'm building. I've an xml file being read into an app. This XML is of the following structure:

     `<Tabs>
      <Tab>
        <Search name="ListSearch" Title="SearchHeader">
          <Label Name="lblSchema"></Label>
          <ComboBox Name="comboxSchema" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableSchema}" SelectedValue="{Binding SelectedSchema}" />
          <ComboBox Name="comboxList" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableList}" SelectedValue="{Binding SelectedList}" />
          <Label Name="lblCriteria"></Label>
          <ComboBox Name="comboxFields" Visibility="Visible" IsEnabled="True" ItemSource="{Binding AvailableFields}" SelectedValue="{Binding SelectedField}" />
          <ComboBox Name="comboxOperator" Visibility="Visible" IsEnabled="True" ItemSource="{Binding Operations}" SelectedValue="{Binding SelectedOperator}" />
          <TextBox Name="txtBoxInputValue" Visibility="Visible" IsEnabled="True" Text="{Binding InputValue}" />
          <CustomControl type="DatePicker"></CustomControl>
          <Button Name="btnAddQueryLine" Content="{Binding TextOnAddQueryButton}" Command="{Binding CamlAddQueryLine}" Action="Publish"></Button>
          <Button Name="btnPasteQueryLine" Content="{Binding TextOnPasteQueryButton}" Command="{Binding CamlPasteQueryLine}" Action="Preview"></Button>
          <Button Name="btnRemoveQueryLine" Content="{Binding TextOnRemoveQueryButton}" Command="{Binding CamlRemoveQueryLine}" Action="UnPublish"></Button>
          <Button Name="btnClearQuery" Content="{Binding TextOnClearQueryButton}" Command="{Binding CamlClearQuery}" Action="UnPreview"></Button>
          <Button Name="btnCamlSearch" Content="{Binding TextOnSearchQueryButton}" Command="{Binding CamlSearch}" Action="Meh"></Button>
          <Button Name="btnCloseSearch" Content="{Binding TextOnCloseQueryButton}" Command="{Binding CloseSearch}" Action="NewMeh"></Button>
        </Search>
      </Tab>
    
      </Tabs>` 
    

    So I read in the xml, and use methods like this to add buttons etc to the ribbon:

    private void AddButtonToGroup(string header,RibbonGroup group,string command,string action)
        {
             RibbonButton button = new RibbonButton();
             button.Label = header;
             button.Name = action;
    
             button.Click += new RoutedEventHandler(button_Click);
             group.Items.Add(button);
        }
    

    with the following event handler:

    void button_Click(object sender, RoutedEventArgs e)
        {
            Button clicked = (Button)sender;
    
            MessageBox.Show("Button Clicked!");
            MessageBox.Show("Performing Action:" + clicked.Name);
    
        }.
    

    The problem I have, is that this isn't the requirement- the event handler is hard coded. Is there any way to create event handlers dynamically? Can anyone point me in the right direction?