使用 List<Tuple<long, long, string>> ItemsSource 在 ComboBox 上绑定多个 SelectedValuePath/Select

Posted

技术标签:

【中文标题】使用 List<Tuple<long, long, string>> ItemsSource 在 ComboBox 上绑定多个 SelectedValuePath/SelectedValue【英文标题】:Multiple SelectedValuePath/SelectedValue binding on ComboBox with List<Tuple<long, long, string>> ItemsSource 【发布时间】:2021-09-22 17:51:24 【问题描述】:

我有一个ComboBox,其中有一个ItemSourceList&lt;Tuple&lt;long, long, string&gt;&gt;。在元组中 Item3 是一些用户友好的显示文本,Item1Item2 是两个不同(但一对一相关)的序列/键,当用户更改绑定对象时,我需要更新它们选定的项目。

我可以像这样轻松地绑定这些序列之一:

<ComboBox ItemsSource="Binding MyList, Mode=OneWay"
          DisplayMemberPath="Item3"
          SelectedValuePath="Item1"
          SelectedValue="Binding MyObject.FirstSequence, Mode=TwoWay"

我想要达到的目标是:

<ComboBox ItemsSource="Binding MyList, Mode=OneWay"
          DisplayMemberPath="Item3"
          SelectedValuePath1="Item1"
          SelectedValue1="Binding MyObject.FirstSequence, Mode=TwoWay"
          SelectedValuePath2="Item2"
          SelectedValue2="Binding MyObject.SecondSequence, Mode=TwoWay"

是否有可能通过多重绑定来实现这样的目标?

我尝试在MyObject.FirstSequence 的设置器中设置MyObject.SecondSequence 但是MyObject.FirstSequenceMyObject.SecondSequence 最初也是从数据库中填充的,我只需要在用户进行更改时更新它们,所以这将在 99% 的情况下会增加相当多的额外和不必要的开销。

我可能会将MyObject.FirstSequenceMyObject.SecondSequence 更改为包含两个序列的类,如下所示:

class Sequences

    string DisplayText  get; set; 
    long FirstSequence  get; set; 
    long SecondSequence  get; set; 

然后将ComboBox.ItemsSource 设置为List&lt;Sequences&gt; 并绑定到MyObject.Sequences,但这将意味着很多其他代码更改,我想先探索其他选项。

【问题讨论】:

因为它是一个视图模型,并且视图模型旨在根据视图的需要进行定制,我推荐@Clemens 方法。这是在视图和 VM(和模型)中将数据获取到所需位置的简洁直接的方法。由于 MyObject 似乎与 3 个元组值部分相关,因此将 MyObject 列表绑定到 Combo(而不是元组列表)可能是一个想法,然后只需选择/绑定所需的 MyObject。但听起来这似乎需要太多的重构工作。时间总是很宝贵的,至少对您的客户而言... 事后看来,我一开始就不会走这条路,但随着时间的推移,需求发生了变化,它突然又回来咬我们了!感谢您的意见。 【参考方案1】:

视图模型可以有一个SelectedTuple 属性来设置MyObject 的属性:

private Tuple<long, long, string> selectedTuple;

public Tuple<long, long, string> SelectedTuple

    get => selectedTuple;
    set
    
        selectedTuple = value;
        MyObject.FirstSequence = selectedTuple.Item1;
        MyObject.SecondSequence = selectedTuple.Item2;
        NotifyPropertyChanged(nameof(SelectedTuple));
    

它的设置如下所示 - 最初,但也可能在附加到 MyObjectPropertyChanged 事件处理程序中。

SelectedTuple = MyList.FirstOrDefault(t =>
    t.Item1 == MyObject.FirstSequence && t.Item2 == MyObject.SecondSequence);

SelectedTuple 属性应该是这样的:

<ComboBox ItemsSource="Binding MyList"
          SelectedItem="Binding SelectedTuple"
          DisplayMemberPath="Item3"/>

【讨论】:

啊,这可能是要走的路。谢谢!

以上是关于使用 List<Tuple<long, long, string>> ItemsSource 在 ComboBox 上绑定多个 SelectedValuePath/Select的主要内容,如果未能解决你的问题,请参考以下文章

C# Tuple 创建一个新二元集合

如何将 List<Long> 转换为 Map<Long, Long> [重复]

元组问题@model Tuple<HabasPortal.Models.Profile,List<SelectListItem>>

C# List<long> 如何转换成 List<string> ?(求高手支招)

列表list和元组tuple的区别

List,tuple和array的区别