[英]WPF ComboBox in Datagrid throws error if Binding is NULL
我有一个要编辑的DataGrid。 一列是组合框
<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay}"
SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="Company" >
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Company.Name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
问题是,如果公司为null
那么我会收到错误消息
双向绑定需要Path或XPath
我如何解决这个问题,以允许将Company设置为null?
Text="{Binding Company.Name}"
始终要求Company
为有效对象,因为系统最终希望访问Name
属性。 我仍然希望您可以创建一个虚拟Company对象并将Name设置为空字符串。 否则,转换器将帮助:
<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay}"
SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" >
<DataGrid.Resources>
<local:MyConverter x:Key="MyConverter"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn Header="Company" >
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Company, Converter={StaticResource MyConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
public class MyConverter : IValueConverter
{
public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
{
return string.Empty;
}
Type myType = value.GetType ();
PropertyInfo pinfo = myType.GetProperty ("Name");
if (pinfo == null)
{
return string.Empty;
}
return (string)pinfo.GetValue(value);
}
public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
转换器使用反射来访问Name
属性。 如果转换器可以访问Company
类型(并且逻辑允许),那么您当然可以直接使用。
该问题已经有了正确的答案,因此这只是快速跟进。 让我们假设一个演示ViewModel:
public MyViewModel()
{
CompanyType companyA = new CompanyType();
companyA.Name = "Comp. A";
CompanyType companyB = new CompanyType();
companyB.Name = "Comp. B";
Companies.Add(companyA);
Companies.Add(companyB);
PersonType person1 = new PersonType();
person1.Id = 1;
person1.Company = null;
PersonType person2 = new PersonType();
person2.Id = 2;
person2.Company = companyB;
persons.Add(person1);
persons.Add(person2);
}
现在,在ComboBox中不起作用的是,在从ComboBox中选择了另一个公司的新值之后,它并没有在更改Person's Company的值:在演示中,我们想将person1和2都分配给来自用户界面。
此外,如果我们不将ComboBox的SelectedItem
绑定到PersonType的Company属性, 则不在person2的ComboBox中选择CompanyB。
在这里,您可以找到针对组合框Xaml的修复程序
<DataTemplate>
<ComboBox
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedItem="{Binding Company}"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
</DataTemplate>
我的演示课程
public class PersonType // don't need to notify below
{
public int Id { get; set; }
public CompanyType Company { get; set; }
}
public class CompanyType
{
public string Name { get; set; }
}
还请注意 ,由于Combobox SelectedItem
的绑定,person2的开头选择了ComboBox项目CompanyB,现在可以将其Company更改为CompanyA。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.