Reputation: 1971
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:
Is it possible to make a DataGridTemplateColumn
be BOUND, so that the above code would work? Can I bind it somehow to a property?
Or do I need to something entirely different, and change the code above?
Thanks in advance!
AT
Upvotes: 26
Views: 85834
Reputation: 1858
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>
Upvotes: 3
Reputation: 1191
No, because DataGridTemplateColumn
doesn't inherit from DataGridBoundColumn
, so the cast to DataGridBoundColumn
would fail.
To make above code work all of your columns must inherit from DataGridBoundColumn
abstract class. So making custom derived Column classes instead of DataGridTemplateColumn
should work.
You could simply populate a
Dictionary<DataGridColumn, string> BoundPropName;
on initialization and then do
var propName = BoundPropName[dgch.Column]
Upvotes: 0
Reputation: 39
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
Upvotes: 3
Reputation: 2086
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.
Upvotes: 38