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

发布于 2024-11-19 08:44:30 字数 1972 浏览 5 评论 0原文

我的组合框的下拉列表(itemssource)包含新产品请求项目。 我想要绑定到不在下拉列表中的旧数据。为了使事情复杂化,我使用多重绑定与 IMultiValueConverter 来组合要显示的字段。此外,绑定字段的名称与我绑定的属性的名称不匹配。

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

我已成功显示并保存新项目。 问题是我还没有弄清楚如何显示不在列表中的旧数据。它不在列表中,因为它不再符合产品请求的条件。

这是问题 XAML(项目源在代码隐藏中设置):

<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>

我使用基于 此 MSDN 杂志示例,来自 Julie Lerman。当然,在本例中我没有使用数据网格。

预先感谢您的任何帮助。

The drop-down list (itemssource) of my combobox contains new product request items. I want to bind to legacy data that is not in the drop-down list. To complicate things I'm using multibinding with an IMultiValueConverter to combine fields for display. Also, the names of bound fields do not match the names of the properties I'm bound to.

The combobox itemssource is a list of NewProductRequests. From this NPR object NewProdNumber and NewProdName are combined for display in the drop-down list by my type converter. The ConvertBack method returns the values NewProdNumber and NewProdNumberCombinedWithName. These two values will be saved to database fields with slightly different names. For this example I'll call them DBProdRequestNumber and DBProdRequestTitle.

I've succeeded in displaying and saving new items. The problem is I haven't figured out how to display legacy data that is not in the list. It's not in the list because it no longer qualifies as a new product request.

Here is the problem XAML (the itemssource is set in code-behind):

<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>

A similar problem with a datagrid and combobox I solved using a DataGridTemplateColumn.CellEditingTemplate based on this MSDN Magazine example from Julie Lerman. Of course, in this case I'm not using a datagrid.

Thanks in advance for any help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巨坚强 2024-11-26 08:44:30

这个答案(针对我自己的问题)是从 NathanAW 答案中的评论中提取的:

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

This answer (to my own question) was pulled from a comment in the NathanAW answer:

Unfortunately I can't include legacy items in the ItemsSource. The list is from a web service that is out of my control. I devised a kludgy solution which I don't really like (but it works)...Since I know the combobox is needed only for new records it is visible only when the user clicks "Add". In the same location I placed a textbox bound to the legacy data that is visible when NOT in add mode. So, I toggle the visiblity of each control as the app switches in and out of add mode. I'm sure there is a better way!

情话已封尘 2024-11-26 08:44:30

看来您可以通过不使用多重绑定转换器来简化此操作。如果您有 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 对象上有其他属性,您可以向模板。

请注意,“选定的”项目以两种方式绑定回 ViewModel 上的属性(或代码隐藏,或其他)。这将类似于:

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

编辑

这是一个示例,它似乎执行您所指示的有关在“SelectionBox”中显示旧数据的操作,但不在下拉列表中显示旧数据。要测试这一点,请尝试在 KaXaml 或其他东西中运行它。然后开始输入“Hello 3”,看到它建议“Hello 30”。这表明组合知道该项目。现在将列表下拉,会发现它不在列表中。如果使用箭头键向下箭头,则会从“Hello 20”跳到“Hello 40”。

下一步是设置模板,以便将 ListBoxItem 模板的可见性绑定到 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>

It seems that you might be able to simplify this by not using a Multi-Binding converter. If you have a collection of NPR objects, then you can set that as the ItemsSource for the listbox. Then use the DataTemplate to format how you want that item displayed.

With this setup, you can construct a template that shows multiple fields from the NPR object in a single TextBlock using something like:

<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>

If you have additional properties on the NPR object that you'd like to access, you can add an additional section to the template.

Notice that the "selected" item is bound two-way back to a property on your ViewModel (or code-behind, or whatever). This would be something like:

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

EDIT

Here is a sample that seems to do what you've indicted about showing legacy data in the "SelectionBox", but not in the drop down list. To test this, try running it in KaXaml or something. Then start typing "Hello 3" and see that it suggests "Hello 30". This indicates that the Combo knows about the item. Now drop the list down and see that it isn't in the list. If you arrow down with the arrow keys, it skips from "Hello 20" to "Hello 40".

The next step would be to setup your templates so that the ListBoxItem template's Visibility is bound to "IsLegacy" on your NPR object. Then add both legacy and new items to the ItemsSource collection and bind to the list.

<ComboBox IsEditable="True">
  <ComboBoxItem >Hello 10</ComboBoxItem>
  <ComboBoxItem >Hello 20</ComboBoxItem>
  <ComboBoxItem Visibility="Collapsed">Hello 30</ComboBoxItem>
  <ComboBoxItem >Hello 40</ComboBoxItem>
</ComboBox>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文