简体   繁体   中英

Why does ComboBox.ItemsSource referencing ListCollectionView change ComboBox.SelectedItem behavior?

Say I have 3 ComboBox controls. Each ItemsSource references the same master list of products. Each SelectedItem references a separate array index of another list of selected products. This all works great, the program works as expected.

Now say I want to filter the master list of products (for example, only those containing a specific string "berry"). Changing the ItemsSource from Products to ProductsView results in 2 things:

  1. The comboboxes are indeed properly filtered
  2. Whenever a selection is made, ALL comboboxes are set to the last selection

Here's the code. Try flipping between ItemsSource="{Binding Path=ProductsView}" and ItemsSource="{Binding Path=Products}"

MainWindow.xaml:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ComboBox ItemsSource="{Binding Path=ProductsView}" SelectedItem="{Binding Path=SelectedProducts[0]}" />
        <ComboBox ItemsSource="{Binding Path=ProductsView}" SelectedItem="{Binding Path=SelectedProducts[1]}" />
        <ComboBox ItemsSource="{Binding Path=ProductsView}" SelectedItem="{Binding Path=SelectedProducts[2]}" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Data;

namespace WpfApplication2
{
    public partial class MainWindow : Window
    {
        public List<Product> Products { get; set; }
        public ListCollectionView ProductsView { get; set; }
        public ObservableCollection<Product> SelectedProducts { get; set; }

        public MainWindow()
        {
            Products = new List<Product>();
            Products.Add(new Product { Name = "Apple" });
            Products.Add(new Product { Name = "Orange" });
            Products.Add(new Product { Name = "Banana" });
            Products.Add(new Product { Name = "Pear" });
            Products.Add(new Product { Name = "Strawberry" });
            Products.Add(new Product { Name = "Raspberry" });

            ProductsView = new ListCollectionView(Products);
            ProductsView.Filter = (x) => (x as Product).Name.Contains("berry");

            SelectedProducts = new ObservableCollection<Product>();
            SelectedProducts.Add(null);
            SelectedProducts.Add(null);
            SelectedProducts.Add(null);

            InitializeComponent();
            DataContext = this;
        }
    }

    public class Product
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

When using a view the SelectedItem is synchronized with the CurrentItem. To suppress the synchronization set property:

IsSynchronizedWithCurrentItem="False"

on the comboboxes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM