Reputation: 2740
I datatemplate a grid header with a button. When the button is clicked, I want to send the uid (which is a property of the grid column(parent)) as the command parameter.
I Tried : 1. Template Binding 2. Relative Source 3. ElementName (doesnt accpet Binding) But nothing seems to work. Any clue, how to bind to a parent's property in datatemplate?
<UserControl.Resources>
<DataTemplate x:Key="ClickableHeaderTemplate">
<Button x:Name="btn" Content="{Binding}" Background="Transparent"
Command="{Binding DrilldownHeaderClicked}"
CommandParameter="{Binding ElementName=????, Path=Uid}" >
</Button>
</DataTemplate>
</UserControl.Resources>
<DataGrid>
<DataGridTextColumn x:Name="TotalOid" x:Uid="PhMg5Ph-Oid"
Binding="{Binding TotalOid, Mode=OneWay,TargetNullValue=-}"
Header="Col1"
HeaderTemplate="{StaticResource ResourceKey=ClickableHeaderTemplate}">
</DataGridTextColumn>
</Datagrid>
Upvotes: 1
Views: 909
Reputation: 8043
Edit: this a new answer; I left the old answer at the bottom.
If you set Path=. in the CommandParameter you get the ContentPresenter as the object in the Command. At this point I still could not reference the Uid or Name of the Column. Thus I created DataGridTextColumnWithTag that inherits from DataGridTextColumn and I added a DependencyProperty called Tag. Now in OnDrilldownHeaderClicked I can determine the column clicked on in the Grid.
Here is the DataTemplate in XAML:
<Window.Resources>
<c:CommandReference x:Key="DrilldownHeaderClickedReference" Command="{Binding DrilldownHeaderClicked}" />
<DataTemplate x:Key="ClickableHeaderTemplate">
<Button Content="{Binding}" Background="Transparent"
Command="{StaticResource DrilldownHeaderClickedReference}"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=.}" >
</Button>
</DataTemplate>
</Window.Resources>
Here is the definition of the DataGrid Column in XAML:
<Helpers:DataGridTextColumnWithTag
Header="Extra Name"
Tag="234"
Width="SizeToCells"
Binding="{Binding FinalName}"
FontSize="20"
HeaderTemplate="{StaticResource ResourceKey=ClickableHeaderTemplate}">
</Helpers:DataGridTextColumnWithTag>
Here is the new DataGrid column:
public class DataGridTextColumnWithTag : DataGridTextColumn
{
public DataGridTextColumnWithTag() : base() { }
public string Tag
{
get { return (string)this.GetValue(TagProperty); }
set { this.SetValue(TagProperty, value); }
}
public static readonly DependencyProperty TagProperty = DependencyProperty.Register(
"Tag", typeof(string), typeof(DataGridTextColumnWithTag), new PropertyMetadata(string.Empty));
}
Here is Command Binding used to find the column clicked on:
public ICommand DrilldownHeaderClicked { get; set; }
private void OnDrilldownHeaderClicked(object obj)
{
ContentPresenter cp = obj as ContentPresenter;
if (cp != null)
{
DataGridColumnHeader tp = cp.TemplatedParent as DataGridColumnHeader;
if ( tp != null )
{
DataGridTextColumnWithTag column = tp.Column as DataGridTextColumnWithTag;
if ( column != null )
{
string tag = column.Tag;
}
}
}
}
Note: this is the old answer. This code gets the column header, but is brittle if/when the Column name changes.
The following DataTemplate gets me the Header of the column.
I then use the header to figure out the column.
Hopefully this gets you started.
If you can extend this solution please post your answer.
<UserControl.Resources>
<c:CommandReference x:Key="DrilldownHeaderClickedReference" Command="{Binding DrilldownHeaderClicked}" />
<DataTemplate x:Key="ClickableHeaderTemplate">
<Button x:Name="btn" Content="{Binding}" Background="Transparent"
Command="{StaticResource DrilldownHeaderClickedReference}"
CommandParameter="{Binding}" >
</Button>
</DataTemplate>
</UserControl.Resources>
Upvotes: 2