【问题标题】:C# WPF ComboBox - Allow item to be selected only once per listC# WPF ComboBox - 每个列表只允许选择一次项目
【发布时间】:2012-05-28 17:05:48
【问题描述】:

我使用 C#、WPF 并尝试使用 MVVM。所以我有一个 MyObjects 的 ObservableCollection。该列表呈现到 DataGrid 中,MyObject 的一个属性是项目的静态列表,显示在每行的 ComboBoxes 中。

现在我想在此组合框中的一行中选择一个项目,如果之前在另一行中选择了它,则必须将最后一个选择删除为默认值。我该如何管理?我的 MyObjectViewModel 知道它自己的组合框的变化,但它如何告诉 MainViewModel(它持有 MyObjects 的 ObservableCollection)从另一个 MyObject 对象更改最后选择的 ComboBox 项?

【问题讨论】:

  • 你说列表是静态的,对吧?那么你不应该只删除选定的项目,它会自动更新所有行吗?
  • 我不希望它从列表中删除;如果之前有另一个 ComboBox 被此项目选中,则必须删除这个 ComboBox 选择。
  • 为什么不为所有项目“AllItems”使用一个列表,一个用于选定项目“SeledtedItems”,第三个用于可用项目“AvailableItems”,后者是“ AllItems”减去“SelectedItems”。此列表是您绑定到 ComboBox 的 ItemsSource 的列表。每当“SelectedItems”更改时,也会在“AvailableItems”上触发 NotifyPropertyChanged。
  • @SvenG 但如果它绑定到“AvailableItems”,则会从每行的 ComboBox 中删除所选项目。我认为 Op 是说如果选择了一个项目,它应该保留在该行中。
  • @SvenG 也许如果您在每一行中有第三个属性——“SelectedItem”——并将其添加到“AvailableItems”的绑定中?

标签: c# wpf mvvm combobox observablecollection


【解决方案1】:

最好的方法是将绑定焦点更改为 ListCollectionViews,因为这将允许您管理光标。下面是一个例子:

视图模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;

    namespace BindingSample
    {
        public class ViewModel
        {
            private string[] _items = new[] { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };

            public ViewModel()
            {
                List1 = new ListCollectionView(_items);
                List2 = new ListCollectionView(_items);
                List3 = new ListCollectionView(_items);

                List1.CurrentChanged += (sender, args) => SyncSelections(List1);
                List2.CurrentChanged += (sender, args) => SyncSelections(List2);
                List3.CurrentChanged += (sender, args) => SyncSelections(List3);
            }

            public ListCollectionView List1 { get; set; }

            public ListCollectionView List2 { get; set; }

            public ListCollectionView List3 { get; set; }

            private void SyncSelections(ListCollectionView activeSelection)
            {
                foreach (ListCollectionView view in new[] { List1, List2, List3 })
                {
                    if (view != activeSelection && view.CurrentItem == activeSelection.CurrentItem)
                        view.MoveCurrentTo(null);
                }
            }
        }
    }

查看

<Window x:Class="ContextMenuSample.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 Orientation="Vertical">
        <ListBox ItemsSource="{Binding List1}" />
        <ListBox ItemsSource="{Binding List2}" />
        <ListBox ItemsSource="{Binding List3}" />        
    </StackPanel>
</Window>

这将允许您只选择一项。它现在是硬编码的,但可以轻松地使其更灵活地用于其他列表。

【讨论】:

  • 感谢您的回答,但按照您的方式,我需要在每个对象中使用相同的列表。难道不能用静态列表(所有对象一个列表)来做到这一点吗?
  • 只有一个实际列表,在 _items 变量中定义。 List1、List2 和 List3 只是这个静态数据源的视图。
猜你喜欢
  • 1970-01-01
  • 2017-06-28
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 2017-12-08
  • 2023-03-20
相关资源
最近更新 更多