So, I found that the solution was to do some work in the code.
In the AutoGeneratingColumn event, create a DataTemplate with a content control and a custom template selector (I create a selector in Xaml and found it as a resource).
Create a binding for ContentProperty ContentControl named e.PropertyName as the path
Create a new DataGridTemplateColumn and set the new CellTemplate columns to the new DataTemplate
replace e.Column with your new column and suppose the datacontext cells are bound to the dynamic property for this column.
If anyone has any refinement, please feel free to share your thoughts.
thanks
EDIT: as requested by the code for my solution
Custom template selector:
public class CustomDataTemplateSelector : DataTemplateSelector { public List<DataTemplate> Templates { get; set; } public CustomDataTemplateSelector() : base() { this.Templates = new List<DataTemplate>(); } public override DataTemplate SelectTemplate(object item, DependencyObject container) { DataTemplate template = null; if (item != null) { template = this.Templates.FirstOrDefault(t => t.DataType is Type ? (t.DataType as Type) == item.GetType() : t.DataType.ToString() == item.GetType().ToString()); } if (template == null) { template = base.SelectTemplate(item, container); } return template; } }
XAML:
<Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication1" Title="MainWindow" Height="350" Width="525"> <Grid x:Name="ParentControl"> <Grid.Resources> <local:CustomDataTemplateSelector x:Key="MyTemplateSelector" > <local:CustomDataTemplateSelector.Templates> <DataTemplate DataType="{x:Type local:MyCellObject}" > <TextBox Text="{Binding MyStringValue}" IsReadOnly="{Binding IsReadOnly}" /> </DataTemplate> </local:CustomDataTemplateSelector.Templates> </local:CustomDataTemplateSelector> </Grid.Resources> <DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_AutoGeneratingColumn" > </DataGrid> </Grid> </Window>
Code behind:
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { // Get template selector CustomDataTemplateSelector selector = ParentControl.FindResource("MyTemplateSelector") as CustomDataTemplateSelector; // Create wrapping content control FrameworkElementFactory view = new FrameworkElementFactory(typeof(ContentControl)); // set template selector view.SetValue(ContentControl.ContentTemplateSelectorProperty, selector); // bind to the property name view.SetBinding(ContentControl.ContentProperty, new Binding(e.PropertyName)); // create the datatemplate DataTemplate template = new DataTemplate { VisualTree = view }; // create the new column DataGridTemplateColumn newColumn = new DataGridTemplateColumn { CellTemplate = template }; // set the columns and hey presto we have bound data e.Column = newColumn; }
Perhaps there is a better way to create a data template that I recently read that Microsoft suggests using XamlReader, but then I did. Also I have not tested this on a dynamic class, but I am sure that it should work anyway.