【问题标题】:A unique item selected for each combobox C# MVVM [closed]为每个组合框 C# MVVM 选择的唯一项目 [关闭]
【发布时间】:2017-11-03 01:04:11
【问题描述】:

我真的不知道该怎么做。所以特地来问你。

在我的窗口上,我有 6 个ComboBox
如果我在 ComboBox 中选择一个项目(例如显示的项目 1),我想为彼此禁用此 item1
如果我下拉第二个ComboBox,我无法选择选择item1 并选择item2
在第三个ComboBox 中,将无法选择item1item2。等等……

我将 WPF 与 MVVM 一起使用。

你能帮帮我吗?

编辑

我已经实施了 Ed Plunkett 的解决方案:
我的转换器: 我获取项目的字符串和包含所选项目的字符串列表

class ComboBoxItemDisableConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values[0].Equals(""))
        {
            return false;
        }

        bool contains = !(values[1] as List<string>).Contains(values[0].ToString());
        return contains;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

我不会向您展示所有 xaml 文件,而只会向您展示重要的代码:
所有ComboBox 都是一样的。

<Window.DataContext>
    <vm:MainViewModel />
</Window.DataContext>
<Window.Resources>
    <converters:ComboBoxItemDisableConverter x:Key="comboBoxItemDisableConverter" />
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <ComboBox Grid.Row="0"
              Grid.Column="0"
              ItemsSource="{Binding ListeComposants}"
              SelectedItem="{Binding SelectedItemPrimaire00}">
        <ComboBox.ItemContainerStyle>
            <Style TargetType="ComboBoxItem">
                <Setter Property="IsEnabled">
                    <Setter.Value>
                        <MultiBinding Converter="{StaticResource comboBoxItemDisableConverter}">
                            <Binding />
                            <Binding Path="DataContext.SelectedItemsVuePrimaire"
                                     RelativeSource="{RelativeSource AncestorType={x:Type Window}}" />
                        </MultiBinding>
                    </Setter.Value>
                </Setter>
            </Style>
        </ComboBox.ItemContainerStyle>
    </ComboBox>

后面没有代码。
在我的 ViewModel 中,我将 SelectedItem 放入名为 ``

List&lt;string&gt;
class MainViewModel : ViewModelBase, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private List<string> _selectedItemsVuePrimaire = new List<string> { "", "", "", "", "", "" };

    public List<string> ListeComposants { get; set; }

    public List<string> SelectedItemsVuePrimaire
    {
        get { return _selectedItemsVuePrimaire; }
        set
        {
            _selectedItemsVuePrimaire = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemsVuePrimaire)));
        }
    }

    private string _selectedItemPrimaire00;

    public string SelectedItemPrimaire00
    {
        get { return _selectedItemPrimaire00; }
        set
        {
            _selectedItemPrimaire00 = value;
            SelectedItemsVuePrimaire[0] = _selectedItemPrimaire00;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemPrimaire00)));
        }
    }

    private string _selectedItemPrimaire01;

    public string SelectedItemPrimaire01
    {
        get { return _selectedItemPrimaire01; }
        set
        {
            _selectedItemPrimaire01 = value;
            SelectedItemsVuePrimaire[1] = _selectedItemPrimaire01;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemPrimaire01)));
        }
    }

    public MainViewModel()
    {
        ListeComposants = new List<string>();
        ListeComposants.Add("");
        ListeComposants.Add("Dernières commandes");
        ListeComposants.Add("Fournisseurs");
        ListeComposants.Add("Relevé de prix");
        ListeComposants.Add("Remises financières");
        ListeComposants.Add("Historique E/S x mois");
        ListeComposants.Add("Prévisions");
        ListeComposants.Add("Equivalences");
        ListeComposants.Add("Caractéristiques");
        ListeComposants.Add("UG");
    }

对于每个第一个打开的下拉列表,下拉列表调用转换器,但如果我第二次打开下拉列表,则不会调用转换器...

解决方案

当 selectedItem 更改时,我添加了我的 selectedItems 列表的 PropertyChanged

    private string _selectedItemPrimaire00;

    public string SelectedItemPrimaire00
    {
        get { return _selectedItemPrimaire00; }
        set
        {
            _selectedItemPrimaire00 = value;
            SelectedItemsVuePrimaire[0] = _selectedItemPrimaire00;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemsVuePrimaire)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItemPrimaire00)));
        }
    }

【问题讨论】:

  • 添加对项目选择的检查以检查它是否在其他组合框中被选中

标签: c# mvvm combobox


【解决方案1】:

给视图模型一个属性,该属性是所有选定项的集合。我们称之为SelectedItems。随着选择的变化更新SelectedItems,并为该集合属性提高PropertyChanged。每个选择都需要绑定到 viewmodel 属性。

为每个 ComboBox 提供一个带有 DataTrigger 的 ItemContainerTemplate。

为 DataTrigger 提供包含 &lt;Binding/&gt;&lt;Binding DataContext.SelectedItems, RelativeSource={RelativeSource AncestorType=ComboBox}}" /&gt; 的多重绑定。如果values[0] (&lt;Binding/&gt;) 包含在values[1] (SelectedItems) 中,则为多重绑定提供一个返回true 的多值转换器(IMultiValueConverter)。

如果多值转换器返回 true,触发器将触发并将 IsEnabled 设置为 False

【讨论】:

  • 如果我在 DataTigger 中使用 MultiBinding,则会出现错误“无法在 'SetterBaseCollection' 集合中使用 'MultiBinding'。”
  • 非常感谢,我找到了解决方案! :D
猜你喜欢
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多