如何将组合框文本绑定到不在下拉列表中的旧数据?

时间:2011-07-11 15:29:29

标签: wpf combobox binding multibinding

我的组合框的下拉列表(itemssource)包含新的产品请求项。 我想绑定到下拉列表中没有的遗留数据。要复杂化我正在使用多重绑定和IMultiValueConverter组合字段进行显示。此外,绑定字段的名称与我绑定的属性的名称不匹配。

组合框itemssource是NewProductRequests的列表。从这个NPR对象NewProdNumber和NewProdName组合在一起,由我的类型转换器显示在下拉列表中。 ConvertBack方法返回值NewProdNumber和NewProdNumberCombinedWithName。这两个值将保存到名称略有不同的数据库字段中。对于这个例子,我将它们称为DBProdRequestNumber和DBProdRequestTitle。

我成功地显示和保存了新项目。 问题是我还没弄清楚如何显示不在列表中的遗留数据。它不在列表中,因为它不再符合产品请求。

以下是XAML的问题(itemssource在代码隐藏中设置):

<ComboBox x:Name="NPRComboBox" IsSynchronizedWithCurrentItem="False" IsEditable="False">
    <ComboBox.SelectedItem>
        <MultiBinding Converter="{StaticResource combineNPRStuffMultiConverter}">
            <Binding Path="DBProdRequestNumber" UpdateSourceTrigger="PropertyChanged"/>
            <Binding Path="DBProdRequestTitle" UpdateSourceTrigger="PropertyChanged"/>
        </MultiBinding>
    </ComboBox.SelectedItem>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock DataContext="{Binding}">
                <TextBlock.Text>
                    <MultiBinding  Converter="{StaticResource combineNPRStuffMultiConverter}">                             
                        <Binding Path="NewProdNumber" UpdateSourceTrigger="PropertyChanged"/>                              
                        <Binding Path="NewProdNumberCombinedWithName" UpdateSourceTrigger="PropertyChanged"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

数据网格和组合框的类似问题我使用基于Julie Lerman的this MSDN Magazine example的DataGridTemplateColumn.CellEditingTemplate解决了这个问题。当然,在这种情况下,我没有使用数据网格。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

这个答案(根据我自己的问题)是从NathanAW答案的评论中删除的:

不幸的是,我不能在ItemsSource中包含遗留项目。该列表来自我无法控制的Web服务。我设计了一个我不喜欢的kludgy解决方案(但它有效)...因为我知道只有新记录才需要组合框,只有当用户点击“添加”时才能看到它。在同一位置,我放置了一个绑定到遗留数据的文本框,当处于NOT模式时,该文本框是可见的。因此,当应用程序切换进入和退出添加模式时,我切换每个控件的可见性。我相信有更好的方法!

答案 1 :(得分:0)

似乎您可以通过不使用多重绑定转换器来简化此操作。如果您有一组NPR对象,则可以将其设置为列表框的ItemsSource。然后使用DataTemplate格式化您希望该项显示的方式。

通过此设置,您可以使用以下内容构建一个模板,该模板在单个TextBlock中显示NPR对象中的多个字段:

<ComboBox 
    x:Name="NPRComboBox" 
    IsSynchronizedWithCurrentItem="False" 
    IsEditable="False" 
    SelectedItem={Binding SelectedNPR, Mode=TwoWay}" 
>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
               <Run Text="{Binding Path=NewProdNumber, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
               <Run> - </Run>
               <Run Text="{Binding Path=NewProdNumberCombinedWithName, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
            </TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

如果您要访问的NPR对象上有其他属性,则可以向模板添加其他部分。

请注意,“selected”项目双向绑定到ViewModel上的属性(或代码隐藏,或其他)。这将是:

public NPR SelectedNPR
{
   get { ... }
   set 
   {
       ...
       // don't forget INotifyPropertyChanged
       ...
   }
}

修改

这是一个示例,它似乎做了你在“SelectionBox”中显示遗留数据但未在下拉列表中显示的内容。要测试这个,尝试在KaXaml或其他东西中运行它。然后开始键入“Hello 3”并看到它显示“Hello 30”。这表明Combo知道该项目。现在放下列表,看看它不在列表中。如果您使用箭头键向下箭头,它会从“Hello 20”跳到“Hello 40”。

下一步是设置模板,以便ListBoxItem模板的Visibility绑定到NPR对象上的“IsLegacy”。然后将旧项和新项添加到ItemsSource集合并绑定到列表。

<ComboBox IsEditable="True">
  <ComboBoxItem >Hello 10</ComboBoxItem>
  <ComboBoxItem >Hello 20</ComboBoxItem>
  <ComboBoxItem Visibility="Collapsed">Hello 30</ComboBoxItem>
  <ComboBoxItem >Hello 40</ComboBoxItem>
</ComboBox>