How to handle button click event for customized DataGridColumnHeader that has DataTemplate

Nov 5, 2008 at 9:49 PM
Hi, I've defined a xaml file for my ResourceDictionary and added a new style for the DataGridColumnHeader which uses a datatemplate to place a button on the right hand side of each column header (code below).

From my inherited datagrid I set the style using the code below:-

            mobjResourceDictionary = New ResourceDictionary
            mobjResourceDictionary.Source = New Uri("SPF/Client/WPF/Resources/SPFListEditResources.xaml", UriKind.Relative)
            ColumnHeaderStyle = mobjResourceDictionary ("SPFListEditColumnHdr")

The button appears but I couldn't work out how to trap the button click event? So I used Command="ApplicationCommands.CancelPrint" on the definition of the button below in the xaml and then used a command binding in my inherited datagrid code to add a handler. This works but I don't think its a great solution and since upgrading from CTP to V1 of the datagrid I get errors in VS2008 saying that it cannot convert string 'CancelPrint' in attribute Command to object of type System.Windows.Input.ICommand.

Is there an alternative for adding a handler? I want to keep the xaml file seperate so other members of the team can modify appearance using blend.

Also the button appears just after the textblock on the header I'd like it tight to the right hand side of the column header and ideally only appear when mouse over the column header (just like windows explorer in Vista). Any ideas?

Thanks in advance.


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  ...
   
    <Style x:Key="SPFListEditColumnHdr" TargetType="{x:Type dgp:DataGridColumnHeader}">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                         AncestorType={x:Type dgp:DataGridColumnHeader}}, Path=Width}"
                                    >
                        <Grid  HorizontalAlignment="Center">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="4*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <TextBlock Text="{Binding}" Margin="0,0,18,0" />
                            <Button Grid.Column="1" Command="ApplicationCommands.CancelPrint"
                                        Opacity="1" MinWidth="12"
                                        ToolTip="Click to filter" Tag="{Binding}"
                                       >
                                <Path x:Name="SortDescIconElement"
                                          Fill="#FF313131" Stroke="#FF313131"
                                          Stretch="Uniform" Width="8"
                                          StrokeThickness="0.5" StrokeLineJoin="Round" Data="F1 M -5.215,0.0L 5.215,0.0L 0,6.099L -5.215,0.0 Z ">
                                </Path>
                            </Button>
                        </Grid>
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>


Coordinator
Nov 6, 2008 at 1:13 PM
You can handle the click event outside of the resource dictionary in a style set on the specfiic instance of the DataGrid:

 

 

<Style x:Key="ColumnHeaderStyle" TargetType="{x:Type dg:DataGridColumnHeader}">
    <EventSetter Event="Button.Click" Handler="ColumnHeader_ButtonClick" />
</Style>

Or you can derive from DataGridColumnHeader and override the OnClick method.  Or, you can add the command like you suggested but outside the resource dictionary. 

Nov 6, 2008 at 3:03 PM
Thanks - its so easy when you know how!!!