我的组合框列表联系人使用MultiBinding绑定到FullName和PhoneExtension。调用IMultiValueConverter的Convert方法,但不调用ConvertBack。为什么? 组合框正确显示列表,但未保存选择。当我标签离开时,它会消失。
背景:
1)联系人列表来自Web服务,并放在后面代码中的可观察集合ContactListObservable中。我没有使用ViewModel。
PhoneBookService phoneBookService = new PhoneBookService();
PhoneRecordArray pbs = GetCompletePhoneListing();
List<PhoneRecord> pbsList = pbs.PhoneArray.ToList();
ObservableCollection<Contact> observableContacts = new ObservableCollection<Contact>();
foreach(PhoneBookService.PhoneRecord rec in pbsList)
{
Contact c = new Contact();
c.FullName = rec.Person;
c.PhoneExtension = rec.Phone;
observableContacts.Add(c);
}
ContactListObservable = observableContacts;
2)组合框位于UserControl上的数据网格中。这就是这种古怪绑定的原因:ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
3)IMultiValueConverter是UserControl.Resources中引用的类<local:CombineNameAndPhoneExtensionMultiConverter x:Key="combinedNameAndPhoneExtensionConverter"/>
4)未在联系人列表中找到的旧版数据必须显示。这是通过DataGridTemplateColumn实现的,它将TextBlock与显示值和ComboBox相结合进行编辑。请参阅this Julie Lerman MSDN article。
这是疯狂的XAML:
<DataGridTemplateColumn x:Name="DataGridContactTemplateColumn" Header="Contact Using Template">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} Ext. {1}">
<Binding Path="FullName"/>
<Binding Path="PhoneExtension"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate x:Name="ContactsCellEditingTemplate">
<Grid FocusManager.FocusedElement="{Binding ElementName=ContactsTemplateComboBox}">
<ComboBox x:Name="ContactsTemplateComboBox" IsSynchronizedWithCurrentItem="False" IsEditable="False" IsDropDownOpen="True" ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock DataContext="{Binding}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource combinedNameAndPhoneExtensionConverter}">
<Binding Path="FullName" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="PhoneExtension" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
我花了太多时间来讨论这个问题,所以我非常感谢你提供的任何帮助。
更多背景资料:
包含我的组合框的数据网格每行包含一个实体框架联系对象,并包含其他联系人字段。以下是一些有效的XAML 成功显示和保存FullName但不保存我想要与FullName一起保存的电话分机:
<DataGridTemplateColumn x:Name="DataGridContactTemplateColumn" Header="Contact Using Template">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=FullName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate x:Name="ContactsCellEditingTemplate">
<Grid FocusManager.FocusedElement="{Binding ElementName=ContactsTemplateComboBox}">
<ComboBox x:Name="ContactsTemplateComboBox" ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" DisplayMemberPath="FullName" SelectedValuePath="FullName" Text="{Binding Path=FullName}" SelectedItem="{Binding Path=FullName}" IsSynchronizedWithCurrentItem="False" IsEditable="False" IsDropDownOpen="True"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
答案 0 :(得分:2)
TextBlock永远不会更改它的Text属性,因此没有理由调用ConvertBack方法。您需要绑定到ComboBox的SelectedItem或Text属性才能获得更新。
答案 1 :(得分:0)
我正在回答我自己的问题,详细说明CodeNaked的准确答案。 将此问题添加到问题XAML并且一切正常 - 调用ConvertBack并根据需要保存FullName和PhoneExtension:
<ComboBox.SelectedItem>
<MultiBinding Converter="{StaticResource combinedNameAndPhoneExtensionConverter}">
<Binding Path="FullName" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="PhoneExtension" UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding>
</ComboBox.SelectedItem>
这是combinedNameAndPhoneExtensionConverter代码:
public class CombineNameAndPhoneExtensionMultiConverter : IMultiValueConverter
{
public object Convert(object[] values,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture)
{
if (values[0] as string != null)
{
string fullName = (string)values[0];
string phoneExtension = (string)values[1];
string namePlusExtension = fullName + ", " + phoneExtension;
return namePlusExtension;
}
return null;
}
public object[] ConvertBack(object value,
Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture)
{
Contact c = (Contact)value;
string[] returnValues = { c.FullName, c.PhoneExtension };
return returnValues;
}
}
感谢CodeNaked快速回复!