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

C# c确认每个组合框都选择了唯一的值,c#,winforms,combobox,user-controls,C#,Winforms,Combobox,User Controls,我有一个winform和一组组合框,所有组合框中都有相同的列表项 我需要一种方法来确认当用户在每个框中选择完一个值时,他们只选择了每个列表值一次 例: cbox1 cbox2 Cbox3 项目A项目B项目A由于项目A已在cbox1中选择,因此需要标记错误 我想尝试使用SelectedValueCommitted操作,因为在填充列表后,我将所选索引更改为-1,这样它们在开始时都显示为空,但使其工作的循环似乎无法实现 背景:这是选择字段来构建电子表格,用户需要选择字段顺序。您可以像这样快速完成: 在

我有一个winform和一组组合框,所有组合框中都有相同的列表项

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

例: cbox1 cbox2 Cbox3 项目A项目B项目A由于项目A已在cbox1中选择,因此需要标记错误

我想尝试使用SelectedValueCommitted操作,因为在填充列表后,我将所选索引更改为-1,这样它们在开始时都显示为空,但使其工作的循环似乎无法实现


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

您可以像这样快速完成:

在示例中,将所有三个组合框的SelectedIndexChanged处理程序添加到表单\u Load中

comboBox1.SelectedIndexChanged += CheckComboBoxes;
comboBox2.SelectedIndexChanged += CheckComboBoxes;
comboBox3.SelectedIndexChanged += CheckComboBoxes;
在CheckComboBox方法中进行检查:

 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个组合框时的方法。将所有项目放入列表,选择不同的值,并将不同的计数与项目计数进行比较。。。大概是这样的:

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");
}

这里有一个方法,你可以采取

要使受影响的组合框易于区分,请将它们全部放在GroupBox容器中。 为组框编写验证方法。 通过将组框验证事件附加到验证方法来订阅该事件。 在验证方法中,循环检查组框中的所有ComboBox控件,检查是否有重复项,如果有,则发出错误。 例如,假设组框称为groupBox1:

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

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

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

bool cancelling;
然后将以下内容添加到GroupBox1\u验证的开头:


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

可供选择的用户界面设计-A

创建一个ListBox ListFieldsOriginal并填充 创建第二个ListBox ListUserSelection,最初将其保留为空 提供如下按钮:

按钮“>”表示在末尾将当前选定的项目从ListFieldsInial添加到ListUserSelection;并从ListFieldsOriginal中删除该项


按钮“通常您只对所有项目启用一个组合。当用户选择一个项目时,您将启用第二个组合,并在第一个组合中填充没有选择项目的所有内容,然后在第三个组合中依次填充。您可以重建数据源以排除以前的选择,我曾想过这样做,但完整表单将有多达20个组合框。这似乎是一个巨大的if语句。另外,您还需要在用户完成选择后进行验证,否则他们将无法更改顺序。假设有3个选项,A、B和C。如果用户选择了A、B和C,然后认为这是错误的,那么上面的代码不允许您在以后更改。我已经编辑了我的答案,并建议了另一种方法。仅使用字符串值作为组合项进行测试,但您会明白这一点。@Matthew,OfType的良好用法,简化了代码。这是一个向上的投票。我采用了这种方法——我唯一需要将foreach-if语句更改为.Text from.SelectedItem——因为它不起作用,我假设这是由于组合框未绑定到源。
public Form1()
{
    InitializeComponent();
    groupBox1.Validating += GroupBox1_Validating;
}
private void cancelButton_Click(object sender, EventArgs e)
{
    cancelling = true;
    this.Close();
}

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