I\'m struggling with a confluence of problems.
Modify your XAML to:
<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn" CanUserAddRows="False" x:Name="TheDataGrid" ItemsSource="{Binding Data}">
<DataGrid.Resources>
<DataTemplate x:Key="dataItemCellTemplate">
<ComboBox ItemsSource="{Binding [Option].Options}" SelectedValue="{Binding [Option].SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGrid.Resources>
</DataGrid>
Where [Option]
refers to the column of DataView
in which you store your custom DataItem
objects.
Dusan's answer set me on the right track. Because I don't know the column names until runtime, I have to create the data template at runtime too. It's actually not difficult.
private DataTemplate GetDataTemplate(string columnName)
{
string xaml = "<DataTemplate><ComboBox SelectedValue=\"{Binding Path=[" + columnName +
"].SelectedEnumeratedElementItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"" +
" ItemsSource=\"{Binding Path=[" + columnName +
"].Items}\" DisplayMemberPath=\"Name\"/></DataTemplate>";
var sr = new MemoryStream(Encoding.ASCII.GetBytes(xaml));
var pc = new ParserContext();
pc.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
pc.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
var datatemplate = (DataTemplate)XamlReader.Load(sr, pc);
return datatemplate;
}
I dont know how to do this with DataTemplate
from XAML
resources, but it work fine for me with DataTemplate
created in code.
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
System.Windows.Controls.DataGridTemplateColumn templateColumn = new System.Windows.Controls.DataGridTemplateColumn();
templateColumn.Header = e.PropertyName;
DataTemplate template = new DataTemplate();
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(StackPanel));
template.VisualTree = factory;
FrameworkElementFactory childFactory = new FrameworkElementFactory(typeof(TextBox));
childFactory.SetBinding(TextBox.TextProperty, new Binding(e.PropertyName));
factory.AppendChild(childFactory);
templateColumn.CellEditingTemplate = template;
template = new DataTemplate();
factory = new FrameworkElementFactory(typeof(StackPanel));
template.VisualTree = factory;
childFactory = new FrameworkElementFactory(typeof(TextBlock));
childFactory.SetBinding(TextBlock.TextProperty, new Binding(e.PropertyName));
factory.AppendChild(childFactory);
templateColumn.CellTemplate = template;
e.Column = templateColumn;
}