WPF - How to bind a DataGridTemplateColumn

74,516

Solution 1

Although you can't bind a template column, you can bind one of the controls held in that column. This is how I solved a similar problem:

<DataGridTemplateColumn Header="ColumnHeader">
     <DataGridTemplateColumn.CellTemplate>
           <DataTemplate>
                 <local:CustomisedUIElement Text="{Binding Path=PropertyToBindTo}"/>
           </DataTemplate>
     </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

If I've understood the initial example properly, this would mean changing the logic of the GroupByField_Click() method to check whether the sending column was a template column and then looking at the elements it contained to obtain the Binding object.

Solution 2

It's a tricky one. We achieved the binding by traversing to its grandparent UserControl (we had DataGrid inside a UserControl) and the UserControl was bound to a Presenter (Model in our case). In the code below, check the property SelectedItem of AutoCompleteBox placed inside the DataGridTemplateColumn.

<wpfToolkit:DataGridTemplateColumn  Header="{x:Static resources:Store.ItemNameC}" Width="0.60*">
  <wpfToolkit:DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <extended:HOAutoCompleteBox
                            IsTextCompletionEnabled ="True"
                            x:Name="ItemAutoCompleteBox"
                            Populating="ItemAutoCompleteBox_Populating"
                            DefaultType="HealthObject.ObjectModel.pSearchStockItemResult,HealthObject.ObjectModel"
                            Text="{Binding Path= ItemName, Mode=TwoWay}" 
                            <!--- **** HERE IS THE BINDING SAMPLE *****-->
            SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},  Path=Model.SelectedStockItem, Mode=TwoWay}">
        </extended:HOAutoCompleteBox>
    </DataTemplate>
  </wpfToolkit:DataGridTemplateColumn.CellEditingTemplate>

</wpfToolkit:DataGridTemplateColumn>

Solution 3

For me, ClipboardContentBinding of DataGridTemplateColumn is a solution:

Private Function FindBoundProperty(ByVal col As DataGridColumn) As String

    Dim boundColumn As DataGridBoundColumn = TryCast(col, DataGridBoundColumn)
    Dim boundPropertyName As String = ""
    Dim binding As Binding
    If col.DependencyObjectType.Name = "DataGridTextColumn" Then
        binding = TryCast(boundColumn.Binding, Binding)
        boundPropertyName = binding.Path.Path
    End If
    If col.DependencyObjectType.Name = "DataGridTemplateColumn" Then
        binding = TryCast(col.ClipboardContentBinding, Binding)
        boundPropertyName = binding.Path.Path
    End If
    Return boundPropertyName

End Function

Solution 4

You may use dgbc.ClipboardContentBinding;

Share:
74,516
Andy T
Author by

Andy T

Updated on May 12, 2020

Comments

  • Andy T
    Andy T about 4 years

    I am trying to get the name of the property associated with a particular DataGridColumn, so that I can then do some stuff based on that. This function is called when the user clicks context menu item on the column's header...

    This is fine for the out-of-the-box ready-rolled column types like DataGridTextColumn, since they are bound, but the problem is that some of my columns are DataGridTemplateColumns, which are not bound.

    private void GroupByField_Click (object sender, RoutedEventArgs e){
            MenuItem mi = (MenuItem)sender;
            ContextMenu cm = (ContextMenu) mi.Parent;
            DataGridColumnHeader dgch = (DataGridColumnHeader) cm.PlacementTarget;  
            DataGridBoundColumn dgbc = (DataGridBoundColumn) dgch.Column;
            Binding binding = (Binding) dgbc.Binding;
            string BoundPropName = binding.Path.Path;
    
            //Do stuff based on bound property name here...
        }
    

    So, take for example my Name column... it's a DataGridTemplateColumn (since it has an image and some other stuff in there). Therefore, it is not actually bound to the 'Name' property... but I would like to be, so that the above code will work.

    My question is two-part, really:

    1. Is it possible to make a DataGridTemplateColumn be BOUND, so that the above code would work? Can I bind it somehow to a property?

    2. Or do I need to something entirely different, and change the code above?

    Thanks in advance!

    AT