Search code examples
c#wpfxamldata-bindingdatagrid

Assign Click Event to Button in WPF ResourceDictionary


I keep my theme file (ResourceDictionary) in a separate project. I'm using the following ControlTemplate structure for the DataGrid in my ResourceDictionary:

<Style TargetType="{x:Type DataGridColumnHeader}">

      <Setter Property="ContentTemplate">        

          <Setter.Value>

             <DataTemplate>

                 <StackPanel Orientation="Horizontal">

                     <TextBlock Text="{Binding}" Margin="10 5" />

                     <Button x:Name="btnFilter" Content="&#xf0b0;" FontFamily="{StaticResource FontAwesome}" FontSize="16" />

                 </StackPanel>

             </DataTemplate>

         </Setter.Value>

     </Setter>

 </Style>

Where I use DataGrid in the related project, I need to assign a click event to the button named btnFilter above, how can I do this?

Methods like VisualTree do not work very well. Since I have nearly 20 columns in Datagrid, I use horizontal scroll and VisualTree does not see the columns hidden by scroll.

What are the best practices I should follow here?


Solution

  • As Button.Click is a bubbling routed event, you can listen it at the control nearer to the root.

    For example, assuming you name the Style as "HeaderStyle", it would be like the following.

    <DataGrid ColumnHeaderStyle="{StaticResource HeaderStyle}"
              Button.Click="Button_Click">
        <DataGrid.Columns>
            <DataGridTextColumn Header="HeaderText"/>
        </DataGrid.Columns>
    </DataGrid>
    

    In case there are multiple Buttons in that control, you can filter by checking RoutedEventArgs.OriginalSource.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (e.OriginalSource is Button { Name: "btnFilter" })
        {
            // Handle event here.
        }
    }