Aaron
Aaron

Reputation: 1323

DataGridColumnHeader with StackPanel, bind content of TextBlock/Label to ColumnName, dynamic grid

I have a dynamically generated DataGrid bound to a DataTable property in my ViewModel.

I have AutoGenerateColumnHeaders = true, and it's working fine. However, I'm using a DataTemplate to cover the Header with a StackPanel containing a Label and Button. I cannot seem to figure out how to bind the Label Content to the DataGridColumnHeader. I have tried with and without FindAncestor, but I believe the following is the closest to where I need to be...Question is on the Label Content="{}"

<local:UserControlViewBase.Resources>
    <Style TargetType="DataGridColumnHeader">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border BorderBrush="Black" BorderThickness="1">
                        <StackPanel Width="Auto" Orientation="Horizontal">
                            <Label Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:UserControlViewBase}},Path=DataContext.TestList.ColumnName}" Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            <Button Content="Ok" Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</local:UserControlViewBase.Resources>

//local:UserControlViewBase is just a UserControl with some extra bells and whistles added.

I'm fairly new to WPF and I'm assuming I'm just missing something with the binding - I'm still learning. Thanks.

Upvotes: 1

Views: 268

Answers (2)

Rye bread
Rye bread

Reputation: 1811

The DataGridColumnHeader can access the object bound to Header in the standard way. No workarounds are needed.

Using a Label:

<Style TargetType="{x:Type DataGridColumnHeader}">               
                <Setter Property="Template">
                    <Setter.Value>
                        <!-- This displays a column heading: -->
                        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                            <Grid>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="30"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                   
                                    <!-- This contains the heading text -->
                                    <Label Content="{Binding Path=.}"/>                                   </Grid>
                            </Grid>
                         </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

Using a ContentPresenter:

<Style TargetType="{x:Type DataGridColumnHeader}">               
                <Setter Property="Template">
                    <Setter.Value>
                        <!-- This displays a column heading: -->
                        <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                            <Grid>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="30"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                    </Grid.ColumnDefinitions>
                                   
                                    <!-- This contains the heading text -->
                                    <ContentPresenter />
                               </Grid>
                            </Grid>
                         </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

Upvotes: 0

Aaron
Aaron

Reputation: 1323

This is what I did to get it to work. I had to change the findancestor to look for the DataGridColumnHeader instead of the user control. I then was able to access the Column.Header property:

<local:UserControlViewBase.Resources>
    <Style TargetType="DataGridColumnHeader">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border BorderBrush="Black" BorderThickness="1">
                        <StackPanel Width="Auto" Orientation="Horizontal">
                            <Label Width="75" Content="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGridColumnHeader}},Path=Column.Header}" Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                            <Button Content="Ok" Padding="12,0,12,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</local:UserControlViewBase.Resources>

Upvotes: 0

Related Questions