问题描述
我正在努力解决各种问题。
I'm struggling with a confluence of problems.
- 我有一个动态数据集,可以手动将其组装成一个DataTable。
- 由于数据不是静态的,我必须自动生成列。
- 我需要将组合框的ItemsSource绑定到定义的Observable集合在每个单元格中。
尽管我认为这很容易,但是ComboBox无法在DataView中看到DataItem,而是尝试绑定
Although I thought it would be easy, the ComboBox cannot see the DataItem in the DataView, rather it tries to bind to the DataView directly.
我在这里整理了一个示例项目:
I've put together a sample project here:
现在,显然是想证明这个问题。我目前无法更改数据结构,因此任何解决方案都必须在XAML中完成。
Now, it's obviously contrived to demonstrate the issue. I can't change the data structure at this point, so any solution must be done in the XAML.
要查看问题,请使用Snoop(或等效工具)查看
To see the problems, use Snoop (or equivalent) to see the binding errors on the ComboBoxes.
DataGrid的设置如下:
The DataGrid is set up like so:
<DataGrid AutoGenerateColumns="True" AutoGeneratingColumn="DataGrid_OnAutoGeneratingColumn" CanUserAddRows="False" x:Name="TheDataGrid" ItemsSource="{Binding Data}">
<DataGrid.Resources>
<DataTemplate x:Key="dataItemCellTemplate">
<ComboBox SelectedValue="{Binding Path=SelectedOption, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Options}"/>
</DataTemplate>
</DataGrid.Resources>
</DataGrid>
自动生成的事件处理程序为:
And the event handler for the autogeneration is:
private void DataGrid_OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType == typeof(string))
{
var col = new DataGridTextColumn {Binding = new Binding(e.PropertyName), Header = e.PropertyName};
e.Column = col;
}
else if (e.PropertyType == typeof(DataItem))
{
var col = new DataGridTemplateColumn
{
CellTemplate = (DataTemplate) TheDataGrid.FindResource("dataItemCellTemplate"),
CellEditingTemplate = (DataTemplate)TheDataGrid.FindResource("dataItemCellTemplate"),
Header = e.PropertyName
};
e.Column = col;
}
}
组合上的绑定错误为:
System.Windows.Data错误:40:BindingExpression路径错误:在对象 DataRowView(HashCode = 22264221)上找不到 Options属性。 BindingExpression:Path = Options; DataItem = DataRowView(HashCode = 22264221);目标元素是组合框(名称=);目标属性是 ItemsSource(类型为 IEnumerable)
System.Windows.Data Error: 40 : BindingExpression path error: 'Options' property not found on 'object' ''DataRowView' (HashCode=22264221)'. BindingExpression:Path=Options; DataItem='DataRowView' (HashCode=22264221); target element is 'ComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
System.Windows.Data错误:40:BindingExpression路径错误:在对象上找不到 SelectedOption属性''DataRowView'(HashCode = 22264221)'。 BindingExpression:Path = SelectedOption; DataItem = DataRowView(HashCode = 22264221);目标元素是组合框(名称=);目标属性是 SelectedValue(类型为对象)
System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedOption' property not found on 'object' ''DataRowView' (HashCode=22264221)'. BindingExpression:Path=SelectedOption; DataItem='DataRowView' (HashCode=22264221); target element is 'ComboBox' (Name=''); target property is 'SelectedValue' (type 'Object')
推荐答案
Dusan的答案使我处于正确的轨道。因为直到运行时才知道列名,所以我也必须在运行时创建数据模板。
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;
}
这篇关于DataGridTemplateColumns,AutoGenerateColumns = true并绑定到DataTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!