c# 确认每个组合框都选择了唯一值

c# confirm each combobox has a unique value selected

我有一个带有一组组合框的 winform,所有组合框都包含相同的列表项。

我需要一种方法来确认,当用户在每个框中完成选择一个值时,他们只选择了每个列表值一次。

例如: cbox1 cbox2 cbox 3 项目 A 项目 B 项目 A(这需要标记错误,因为项目 A 已经在 cbox1 中被选中)

我正在考虑尝试使用 selectedvaluecommited 操作(因为在我填充列表后我将所选索引更改为 -1 所以它们都显示 "empty" 开始)但是使它工作的循环似乎躲着我。

背景:这是选择字段来构建电子表格,用户需要选择字段顺序。

你可以这样做(又快又脏):

为所有三个组合框添加 SelectedIndexChanged 处理程序(在 Form_Load 示例中)

comboBox1.SelectedIndexChanged += CheckComboBoxes;
comboBox2.SelectedIndexChanged += CheckComboBoxes;
comboBox3.SelectedIndexChanged += CheckComboBoxes;

在 CheckComboBoxes 方法中进行检查:

 private void CheckComboBoxes(object sender, EventArgs e)
 {
     if (comboBox1.SelectedIndex == comboBox2.SelectedIndex ||
         comboBox1.SelectedIndex == comboBox3.SelectedIndex ||
         comboBox2.SelectedIndex == comboBox3.SelectedIndex)
             MessageBox.Show("comboboxes are not unique");
 }

编辑: 这是具有 n 组合框时的方法。将所有项目放入列表中,select 个不同的值并将该不同的计数与项目计数进行比较...像这样:

private void CheckComboBoxes(object sender, EventArgs e)
{
    List<string> comboValues = new List<string>();
    foreach (Control c in this.Controls)
    {
        if (c is ComboBox && !string.IsNullOrEmpty((c as ComboBox).SelectedItem.ToString()))
        comboValues.Add((c as ComboBox).SelectedItem.ToString());
    }
    if (comboValues.Distinct().ToList().Count < comboValues.Count)
        MessageBox.Show("not all combos are unique");
}

您可以采用以下方法。

  1. 为了使受影响的组合框易于区分,将它们全部放在一个 GroupBox 容器中。
  2. 为您的组框写一个验证方法。
  3. 通过将分组框 Validating 事件附加到您的验证方法来订阅它。
  4. 在您的验证方法中,循环遍历组合框中的所有 ComboBox 控件并检查是否有任何重复项,如果有则发出错误。

例如,假设组框名为 groupBox1:

private void GroupBox1_Validating(object sender, CancelEventArgs e)
{
    base.OnValidating(e);
    var selectedIndices = groupBox1.Controls.OfType<ComboBox>().Select(item => item.SelectedIndex);
    var anyDuplicates = selectedIndices.GroupBy(x => x).Any(x => x.Count() > 1);

    if (!anyDuplicates)
        return;

    MessageBox.Show("There are duplicates!");
    e.Cancel = true;
}

并在Form1构造函数中订阅分组框Validating事件:

public Form1()
{
    InitializeComponent();
    groupBox1.Validating += GroupBox1_Validating;
}

有时像这样进行验证时,如果用户单击“取消”按钮,您需要阻止执行验证逻辑。您应该能够将“取消”按钮的 CausesValidation 属性 设置为 false 以防止出现这种情况,但我发现它对我不起作用。

相反,我只使用 bool cancelling 字段,我在取消按钮处理程序中将其设置为 true:

private void cancelButton_Click(object sender, EventArgs e)
{
    cancelling = true;
    this.Close();
}

bool cancelling;

然后将以下内容添加到 GroupBox1_Validating() 的开头:

if (cancelling)
    return;

如果可以有不同的 UI 设计,那么我的建议如下:

备选 UI 设计 - A

  1. 创建一个 ListBox ListFieldsOriginal 并填充
  2. 创建第二个 ListBox ListUserSelection,最初保持为空
  3. 提供如下按钮:

    按钮'>'表示将当前选中的项目从ListFieldsOrginial 添加到最后的ListUserSelection;并从 ListFieldsOriginal

    中删除该项目

    按钮“<”表示从 lstUserSelection 中删除当前选择的项目;并将该项目添加回 ListFieldsOriginal(当然在最后)

注意:如果将项目添加回 ListFieldsOriginal 是您的要求,则需要额外编码才能在 ListFieldsOriginal 中找到其适当的索引。

备选 UI 设计 - B

  1. 创建一个 CheckedListBox ListFieldsOriginal 并填充
  2. 创建一个ListBox ListUserSelection,一开始留空
  3. 将 ListFieldsOriginal 的 ItemCheck 事件处理程序定义为 add/remove 项 to/from ListUserSelected。

    if (e.CurrentValue==CheckState.Unchecked)
    {
       string item = ListFieldsOriginal.Items[item];
       ListUserSelection.Items.Add(item);
    }
    else
    {
       string item = ListFieldsOriginal.Items[item];
       ListUserSelection.Items.Remove(item);
    }