我正在努力应对各种各样的问题。
虽然我认为这很容易,但ComboBox无法在DataView中看到DataItem,而是尝试直接绑定到DataView。
我在这里整理了一个示例项目:
https://github.com/5flags/DataGridBindingIssue
现在,显然已经设法证明了这个问题。我此时无法更改数据结构,因此任何解决方案都必须在XAML中完成。
要查看问题,请使用Snoop(或等效的)查看ComboBox上的绑定错误。
DataGrid的设置如下:
<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>
自动生成的事件处理程序是:
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)'上找不到'选项'属性。 BindingExpression:路径=选项; DataItem ='DataRowView'(HashCode = 22264221); target元素是'ComboBox'(Name =''); target属性是'ItemsSource'(类型'IEnumerable')
System.Windows.Data错误:40:BindingExpression路径错误:'object'''DataRowView'(HashCode = 22264221)'上找不到'SelectedOption'属性。 BindingExpression:路径= SelectedOption; DataItem ='DataRowView'(HashCode = 22264221); target元素是'ComboBox'(Name =''); target属性是'SelectedValue'(类型'Object')
答案 0 :(得分:3)
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;
}
答案 1 :(得分:2)
我不知道如何使用DataTemplate
资源中的XAML
来执行此操作,但对于我在代码中创建DataTemplate
的情况,它可以正常工作。
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;
}
答案 2 :(得分:1)
将您的XAML修改为:
<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>
[Option]
指的是DataView
列中您存储自定义DataItem
对象的列。