防止两个组合框选择相同的项目

时间:2018-09-12 14:36:16

标签: c# wpf

我正在寻找一种方法来防止两个(或多个)ComboBoxes具有相同的SelectedItem。我有多个ComboBoxes,它们都具有相同的ItemsSource,每个都绑定到视图模型中的单独属性。

<ComboBox Width="50" ItemsSource="{Binding Keys}" SelectedItem="{Binding LoadedBackgroundKey, NotifyOnValidationError=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox Width="50" ItemsSource="{Binding Keys}" SelectedItem="{Binding LoadedForegroundKey, NotifyOnValidationError=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox Width="50" ItemsSource="{Binding Keys}" SelectedItem="{Binding IncreaseSizeKey, NotifyOnValidationError=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

等在ViewModel中:

public Key LoadedBackgroundKey { get; set; }
public Key LoadedForegroundKey { get; set; }
public Key IncreaseSizeKey { get; set; }
private ObservableCollection<Key> _availableKeys;
public IEnumerable<Key> Keys => _availableKeys;

加载视图模型后,将使用适当的键(_availableKeysA等)填充B。我希望能够防止在多个组合框中选择相同的键,或者(至少)在多个框中选择相同的键时给出错误。

This question可能与我想要的类似,但是我不确定它是否可以正常工作(也许我只是不太了解它)。它还仅考虑两个ComboBoxes的情况。虽然我只显示3,但我希望它可以在多个Comboboxes上缩放。 ValidationRule是最好的方法吗?如果是这样,我将如何实现这一点,检查所有ComboBoxes?还是有更简单的方法?

1 个答案:

答案 0 :(得分:2)

只要设置了任何涉及的属性,您就可以在视图模型中实现INotifyDataErrorInfo接口并执行验证逻辑,例如:

public class ViewModel : INotifyDataErrorInfo
{
    public Key LoadedBackgroundKey
    {
        get => keys[0];
        set
        {
            Validate(nameof(LoadedBackgroundKey), value);
            keys[0] = value;
        }
    }

    public Key LoadedForegroundKey
    {
        get => keys[1];
        set
        {
            Validate(nameof(LoadedForegroundKey), value);
            keys[1] = value;
        }
    }

    public Key IncreaseSizeKey
    {
        get => keys[2];
        set
        {
            Validate(nameof(IncreaseSizeKey), value);
            keys[2] = value;
        }
    }

    public IEnumerable<Key> Keys { get; } = new ObservableCollection<Key> { ... };

    private void Validate(string propertyName, Key value)
    {
        if (keys.Contains(value))
            _validationErrors[propertyName] = "duplicate...";
        else
            _validationErrors.Remove(propertyName);

        ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
    }

    private readonly Key[] keys = new Key[3];
    private readonly Dictionary<string, string> _validationErrors = new Dictionary<string, string>();
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
    public bool HasErrors => _validationErrors.Count > 0;
    public IEnumerable GetErrors(string propertyName) =>
        _validationErrors.TryGetValue(propertyName, out string error) ? new string[1] { error } : null;
}