My combobox listing Contacts is bound to both FullName and PhoneExtension using MultiBinding. The Convert method of IMultiValueConverter is called but ConvertBack is not. Why? The combobox properly displays the list but the selection is not saved. It disappears when I tab away.
Background:
1) The Contact list comes from a web service and is put in an observable collection ContactListObservable in the code behind. I'm not using a 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) The combobox is in a datagrid located on a UserControl. That's the reason for this wacky binding: ItemsSource="{Binding ContactListObservable, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
3) The IMultiValueConverter is a class referenced in UserControl.Resources as <local:CombineNameAndPhoneExtensionMultiConverter x:Key="combinedNameAndPhoneExtensionConverter"/>
4) Legacy data NOT found in the Contacts list must display. This is accomplished with a DataGridTemplateColumn by combining a TextBlock to display values and a ComboBox for editing. See this Julie Lerman MSDN article.
Here is the crazy 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>
I've devoted WAY too much time to this so I'll greatly appreciate any help you can offer.
More Background:
The datagrid containing my combobox contains one entity framework contact object per row and includes additional contact fields. Here is some working XAML that succesfully displays and saves FullName but not the phone extension which I want to save in combination with the 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>