johns193 johns193 - 2 months ago 19
C# Question

WPF DataGridTextColumHeaderTemplate bind width to TextColumnWidth of "*"

I have a

DataGrid
with
DataGridTextColum
of
width="*"
(multiple of them, so that they're all divided equally) and I'd like to set the width of this
DataGridTextColumn
's
DataGridTextColumn.Header
to its parent width (
DataGridTextColumn
).

However the code doesn't work, reason is I'm not defining
RelativeSource
correct, so my question is, how do I define
Binding
to
Width
inside
HeaderTemplate
of
DataGridTextColumn
to bind to
DataGridTextColumn.ActualWidth
? Code below!

<DataGridTextColumn Width="*" Binding="{Binding Username}" CanUserReorder="False" CanUserSort="False" x:Name="DataGridTextColumn">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="Red" MouseLeftButtonDown="EventSetter_OnHandler" Width="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType=DataGridTextColumn},Path=ActualWidth, UpdateSourceTrigger=PropertyChanged}">
<Label>Username</Label>
</StackPanel>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
</DataGridTextColumn>


If I change the binding source to ElementName, everything works fine as expected, but i'd like to use RelativeSource to reduce amount of naming that I have to do.

Thanks!

Answer

DataGridColumn is not a FrameworkElement, so it won't appear in the VisualTree. It is merely a information-holder entity. What actually gets rendered is a DataGridColumnHeader for every Column. So, your HeaderTemplate contents would be present in this DataGridColumnHeader. And this DataGridColumnHeader uses its Column property to maintain its association with DataGridColumn. So,

Change your Width of StackPanel to Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridColumnHeader},Path=Column.ActualWidth, UpdateSourceTrigger=PropertyChanged}" .