为什么未在此MultiBinding上调用ConvertBack



我的组合框列表Contacts使用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来实现的。请参阅Julie Lerman MSDN的这篇文章。

这是疯狂的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>

TextBlock永远不会更改其Text属性,因此没有理由调用ConvertBack方法。您需要绑定到组合框的SelectedItem或Text属性才能获得更新。

我回答自己的问题是为了详细说明CodeNaked的准确答案将此添加到问题XAML中,一切正常-调用ConvertBack,并根据需要保存FullName和PhoneExtension:

<ComboBox.SelectedItem>
    <MultiBinding Converter="{StaticResource combinedNameAndPhoneExtensionConverter}">
        <Binding Path="FullName" UpdateSourceTrigger="PropertyChanged"/>
        <Binding Path="PhoneExtension" UpdateSourceTrigger="PropertyChanged"/>
    </MultiBinding>
</ComboBox.SelectedItem>

这是名称和电话扩展的组合转换器代码:

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的快速回复!

相关内容

  • 没有找到相关文章

最新更新