views:

67

answers:

1

Hi, 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>
+1  A: 

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>
Zamboni
CommandParameter="{Binding Uid}"
Tri Q
already tried these. doesnt work.
Mani
@Zamboni - The problem is header of the grid is subjected to localization and will change. so cant use the header text.
Mani
@Mani - I agree, this new answer is a bit better as it works, but I still feel like it can be improved. Let me know if this moves you forward, and please post a new answer if you make improvements.
Zamboni
@zamboni-I have exactly done the same for now and it resolves the problem. Appreciate your effort to get to this. Will follow up with MS folks to get the exact reason for this. Thanks.
Mani