WPF ListBox 多选绑定

3
我有两个listBox,一个在左边,一个在右边。当我在左边的listBox上选择一个“contactList”项目时,右边的listBox应该显示“label”信息,这部分工作得很好。但是我遇到的问题与多选有关,因为目前它只会显示一个选择的信息。我在XAML中更改了Selection mode以进行多选,但似乎没有起作用。感谢任何帮助。谢谢。
XAML
<Grid x:Name="LayoutRoot" Background="#FFCBD5E6">
    <ListBox x:Name="contactsList" SelectionMode="Multiple" Margin="7,8,0,7" ItemsSource="{Binding ContactLists, Mode=Default}" ItemTemplate="{DynamicResource ContactsTemplate}" HorizontalAlignment="Left" Width="254" SelectionChanged="contactsList_SelectionChanged"/>
    <ListBox x:Name="tagsList" Margin="293,8,8,8" ItemsSource="{Binding AggLabels, Mode=Default}" ItemTemplate="{StaticResource TagsTemplate}" Style="{StaticResource tagsStyle}" />
</Grid>

代码

private void contactsList_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
    {
        if (contactsList.SelectedItems.Count > 0)
        {
            CollectionViewGroup collectionView = contactsList.SelectedItems[0] as CollectionViewGroup;
            ContactList selectedContact = contactsList.SelectedItems[0] as ContactList;

            ObservableCollection<AggregatedLabel> labelList = new ObservableCollection<AggregatedLabel>();

            foreach (ContactList contactList in collectionView.Items)
            {
                foreach (AggregatedLabel aggLabel in contactList.AggLabels)
                {
                    labelList.Add(aggLabel);

                    tagsList.ItemsSource = labelList;

                }

            }
        }
    }

1
CollectionViewGroup collectionView = contactsList.SelectedItems[0] as CollectionViewGroup; 我不明白"contactsList.SelectedItems[0]",你只选择了所选项目中的第一项吗? 因此,您只获取第一个项目的标签。 - Notter
谢谢,我认为我选择这种方式是因为我一直遇到一个有趣的空引用异常。有没有办法修改它,以便获取所有选定项的标签? - Ben
你的 tagsList.ItemsSource = labelList; 调用应该在嵌套循环之外。 - John Gardner
2个回答

3

我认为每个人都对这部分感到困惑。

CollectionViewGroup collectionView = contactsList.SelectedItems[0] as CollectionViewGroup;
ContactList selectedContact = contactsList.SelectedItems[0] as ContactList;

您只关注了第一个已选项目(SelectedItems[0]),但是将其视为某个单一的事物或其他东西?

您可能需要类似以下的内容:

// only create the list once, outside all the loops
ObservableCollection<AggregatedLabel> labelList = new ObservableCollection<AggregatedLabel>();

foreach (var selected in contactsList.SelectedItems)
{
   // pretty much your existing code here, referencing selected instead of SelectedItems[0]
}

// only set the list once, outside all the loops
tagsList.ItemsSource = labelList;

理想情况下,您不应该在tagsList上设置items source,而是应该已经将其绑定到一个集合上,并且您只需在此方法中替换内容。(在顶部只需要一次清除集合的调用,不需要调用set ItemsSource,因为它已经被绑定了)


1

我真的不太明白你在那里用那么多代码做什么,但是你通常处理描述的这种情况的方法是直接将第二个ListBox绑定到第一个,应该看起来像这样:

<ListBox Name="ListBox1" ItemsSouce="{Binding SomeOriginalSource}" .../>
<ListBox ItemsSouce="{Binding ElementName=ListBox1, Path=SelectedItems}".../>

编辑:您可以使用DataTemplate枚举内部集合(例如,这可能导致您拥有包含其他ListBox的ListBox),或者将转换器添加到绑定中,将内部集合合并为单个集合,就像John Gardner所指出的那样。


1
假设第二个列表中有某种转换器,可以将每个项目转换为每个项目的聚合标签,那么您可以这样做。 - John Gardner
1
我希望它能够工作,但是由于某些原因,当SelectedItem更改时,PropertyChanged事件没有被触发。 - Vitalij

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接