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

问题描述 投票:0回答:1

我正在寻找一种方法来防止两个(或更多)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;

加载视图模型时,_availableKeys会填充相应的键(AB等)。我希望能够阻止在多个组合框中选择相同的键,或者(至少)在多个框中选择相同的键时给出错误。

This question可能与我正在寻找的类似,但我不确定它是否有效(也许我只是不理解它)。它也只占两个ComboBoxes的情况。虽然我只显示3,但我希望它可以在多个Comboboxes上进行扩展。 ValidationRule是最好的方法吗?如果是这样,我将如何实现这一点,检查所有ComboBoxes?或者有更简单的方法吗?

c# wpf
1个回答
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;
}
© www.soinside.com 2019 - 2024. All rights reserved.