Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically Adding event handlers to WPF

Tags:

c#

wpf

ribbon

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?

like image 375
scarecrow198504 Avatar asked Jan 19 '23 13:01

scarecrow198504


2 Answers

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.

like image 153
Donut Avatar answered Jan 21 '23 11:01

Donut


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;
    }
}
like image 20
alf Avatar answered Jan 21 '23 12:01

alf