c# - WPF ComboBox 选择导致第二个 ComboBox 中的选择

标签 c# wpf xaml mvvm

我将两个组合框绑定(bind)到同一个 ListView 集合。问题在于,在一个组合框中选择一个值会导致另一个组合框所选项目更改为第一个组合框的确切值。它们是耦合的,我希望它们彼此独立。

MyListViewCollection是这样的

modelsView = new ListCollectionView(MainVM.All_Models);

All_Models 是这样的自定义对象的 Observable 集合

public ObservableCollection<MLModel> All_Models { get; set; } = new ObservableCollection<MLModel>() { };

我将两个 ComboBox 绑定(bind)到 modelsview 像这样

<ComboBox ItemsSource="{Binding Path=modelsView}" SelectedItem="{Binding SelectedModel_Right}" SelectionChanged="RightSideModelSelection">

<ComboBox ItemsSource="{Binding Path=modelsView}" SelectedItem="{Binding SelectedModel_Left}" SelectionChanged="LeftSideModelSelection">

所以一切正常,组合框包含模型 View 中相同的项目列表,这就是我想要的。 我确实已将所选项目绑定(bind)到 View 模型中的两个单独的属性,这些属性是

    private MLModel _selectedModel_left;
    public MLModel SelectedModel_Left
    {
        get { return _selectedModel_left; }
        set
        {
            SetProperty(ref _selectedModel_left, value);
        }
    }

    private MLModel _selectedModel_right;
    public MLModel SelectedModel_Right
    {
        get { return _selectedModel_right; }
        set
        {
            SetProperty(ref _selectedModel_right, value);
        }
    }

我唯一能想到的是它们都引用集合中的同一个对象,但我不确定它是如何导致这种行为的。 此外,期望的行为是每个组合框都能够选择并显示同一集合中的不同项目。

任何解释以及将两个组合框选择相互分离的推荐方法都会有所帮助。

编辑:根据要求,这里是创建最小工作示例的代码

MainWindow.xaml

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel Orientation="Vertical">
            <ComboBox ItemsSource="{Binding Path=modelsView}" SelectedItem="{Binding SelectedModel_Left}" >
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}"></TextBlock>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
            <ComboBox ItemsSource="{Binding Path=modelsView}" SelectedItem="{Binding SelectedModel_Right}" >
                <ComboBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}"></TextBlock>
                    </DataTemplate>
                </ComboBox.ItemTemplate>
            </ComboBox>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            DataContext = new ViewModel();
        }
    }
}

MLModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication3
{
    public class MLModel
    {
        public string Name { get; set; }
        public string Type { get; set; }
    }
}

ViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace WpfApplication3
{
    public class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public ViewModel()
        {
            modelsView = new ListCollectionView(All_Models);
            //modelsView.Filter = modelsFilter;
        }
        public ListCollectionView modelsView { get; set; }

        public ObservableCollection<MLModel> All_Models { get; set; } = new ObservableCollection<MLModel>() {
            new MLModel() { Name = "One", Type = "TypeOne" },
            new MLModel() {Name = "Two", Type = "TypeTwo" },
            new MLModel() {Name = "Three", Type = "TypeThree" }
        };

        private MLModel _selectedModel_left;
        public MLModel SelectedModel_Left
        {
            get { return _selectedModel_left; }
            set
            {
                this._selectedModel_left = value;
                NotifyPropertyChanged();
            }
        }

        private MLModel _selectedModel_right;


        public MLModel SelectedModel_Right
        {
            get { return _selectedModel_right; }
            set
            {
                this._selectedModel_right = value;
                NotifyPropertyChanged();
            }
        }
    }
}

最佳答案

来自the documentation :

If the target is an ItemsControl, the current item is synchronized with the selected item.

您在两个 ComboBox 对象之间共享相同的 ListCollectionView。这意味着当前选定的项目在 View 中更新,并在使用相同 View 的任何其他 ItemsControl 中复制。

如果您不希望出现此行为,则需要为每个 ComboBox 提供其自己的要绑定(bind)的 ListCollectionView 对象。

或者,您可以设置 IsSynchronizedWithCurrentItem每个 ComboBox 的属性为 false

关于c# - WPF ComboBox 选择导致第二个 ComboBox 中的选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64124824/

相关文章:

c# - 从 Windows Universal App 中的 ListView 获取选定的 ListViewItem 容器

c# - 使用 XNodeEqualityComparer 或 XElement.DeepEquals 来比较 xml 对象更好吗?

wpf - Web浏览器控件无法播放youtube视频

c# - 通过套接字接收后文本框中的奇怪字符

c# - 有没有办法覆盖列表框中所有项目的颜色?

c# - 如何在 Windows Phone 8 中访问 UserControl 的组件/元素

c# - Xamarin 表单按钮在 iOS 上带有文本和矢量图像

c# - 在 Surface 上的 ScatterView 中使用 LibraryStacks

c# - Azure 表存储 - 从只读 SAS token 创建连接字符串

c# - 如何提供 "Exit"菜单项