scarecrow198504
scarecrow198504

Reputation: 108

Dynamically Adding event handlers to WPF

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?

Upvotes: 4

Views: 11956

Answers (2)

alf
alf

Reputation: 18540

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;
    }
}

Upvotes: 2

Donut
Donut

Reputation: 112825

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.

Upvotes: 7

Related Questions