We are migrating a native WPF DataGrid to a XamDataGrid and we are encountering unexpected behavior.
Our XamDataGrid is bound to an ObservableCollection of ViewModels and includes a TemplateField which encapsulates a user control.
The user control has an Unloading event in which we need to access the row's DataContext (which we expect to be our ViewModel). However, when we interrogate the control within the Load event, its DataContext is a string instead of our ViewModel.
The XAML and codebehind is shown below. Our question is:
How do we get to the row's DataContext (i.e. the DataItem) from the Load Event of a control embedded in a TemplateField?
<igWPF:XamDataGrid Name="dgInfragisticsDataGrid" >
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout Key="MyViewModel">
<igDP:FieldLayout.Fields>
<igDP:TemplateField AlternateBinding="{Binding Path=MyProperty}">
<igDP:TemplateField.DisplayTemplate>
<DataTemplate>
<TextBlock Text="{igEditors:TemplateEditorValueBinding}" HorizontalAlignment="Right"/>
</DataTemplate>
</igDP:TemplateField.DisplayTemplate>
<igDP:TemplateField.EditTemplate>
<MyApp:MyUserControl
Text="{igEditors:TemplateEditorValueBinding}"
Loaded="MyUserControl_Unloaded"/>
</igDP:TemplateField.EditTemplate>
</igDP:TemplateField>
</igDP:FieldLayout.Fields>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igWPF:XamDataGrid>
private void MyUserControl_Unloaded ( object sender, RoutedEventArgs e ){ MyUserControl c = sender as MyUserControl; if (c != null && c.DataContext != null ) { MyViewModel vm = c.DataContext as MyViewModel; // Do some validation and other stuff }}
Thank you
That's great! Glad to help!
Thank you for your timely and thorough response, Rob.
Our user control is now binding correctly and we are able to access the cell's DataContext as shown in your snippets. We have also discovered the DataValueChanged event, so are using in place of the Loaded/Unloaded handling. Beautiful!
Regards,Jeannine
Hi Jeannine,
The XamDataGrid does support editable user controls as long as the binding mode provided is two way. In the code example above the AlternateBinding doesn't have TwoWay set. Also the binding on the user control doesn't have it set. To resolve this you can change the AlternateBinding to
AlternateBinding="{Binding Path=MyProperty, Mode=TwoWay}"
and change your user control Text binding to
Text="{igEditors:TemplateEditorValueBinding Mode=TwoWay}"
As for the DataContext, the DataTemplate provided is being sent to a ContentPresenter's ContentTemplate inside the TemplateEditor. This editor is what manages the switch between the DisplayTemplate and EditTemplate for the TemplateField. The Content of the ContentPresenter is the cell value and this makes the cell value the DataContext for the DataTemplate. In order to access the DataContext for the record you will need to grab it off the TemplateEditor which you can get with an attached property your user control inherits. The code looks like this:
var editor = TemplateEditor.GetEditor(sender as MyUserControl);
The editor's DataContext is going to be a DataRecord which contains the row data in the DataItem property. I.e.:
var item = (editor.DataContext as DataRecord).DataItem as MyDataItem;
Actually, upon further testing, the problem is larger. Our user control bindings are not working. It does not appear that XamDataGrid supports hosting editable user controls in FieldTemplates. Is this so?