我有一个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
,然后我得到的错误
双向绑定需要路径或XPath
我怎样才能解决,为了让公司设置为null?
Text="{Binding 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
是转换器访问(和逻辑允许的话),你当然可以用直接。
这个问题已经有一个正确的答案,所以这只是一个快速跟进。 让我们假设一个演示视图模型:
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中选定后:在演示中,让我们说,我们要同时将与persons1和2至公司A从用户界面。
此外CompanyB 不 PERSON2的组合框选择,如果我们不绑定SelectedItem
的组合框到PersonType的公司财产。
这里你可以找到修复的组合框的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; }
}
请还会注意到 ,由于组合框的绑定SelectedItem
,PERSON2有其ComboBox项CompanyB在一开始选择的 ,现在有可能一个人的公司变更为公司A,例如。