2017-01-24 3 views
2

У меня есть winform с группой comboboxes, все из выпадающих списков с теми же элементами списка в них.C# подтвердить, что у каждого combobox есть уникальное значение, выбранное

Мне нужен способ подтвердить, что, когда пользователь выполнил выбор значения в каждом поле, они только выбрали каждое значение списка один раз.

Ex: cbox1 cbox2 CBOX 3 Пункт А Пункт B Пункт А (это необходимо пометить ошибку, поскольку Пункт А уже выбран в cbox1)

Я думал, пытаясь использовать selectedvaluecommited действие (как после Я заполняю список. Я меняю выбранный индекс на -1, чтобы все они отображали «пустые», чтобы начать), но цикл, чтобы заставить его работать, кажется, ускользает от меня.

background: это выбор полей для создания электронной таблицы, и пользователю необходимо выбрать порядок полей.

+0

Обычно вы держите только один комбо с поддержкой со всеми деталями. когда пользователь выбирает один элемент, вы включаете второй комбо и заполняете все, не выбрав пункт в первом и т. д. для третьего. – Steve

+0

вы можете восстановить источник данных, чтобы исключить предыдущие выборы. Http://stackoverflow.com/a/34829463/1070452 – Plutonix

ответ

1

Вы можете сделать это следующим образом (быстрым и грязным):

Добавить 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"); 
} 

EDIT: Это подход при наличии n comboboxes. Поместите все элементы в списке, выберите различные значения и сравнить, что подсчет различных предметов с кол ... Что-то вроде этого:

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

Я думал об этом так, но полная форма будет иметь до 20 списков. Это похоже на огромное заявление. –

+0

Также вы захотите проверить после того, как пользователь закончил выбор, иначе они не смогут изменить порядок. Предположим, что есть 3 варианта: A, B и C. Если пользователь выбирает A, B и C, а затем решает, что это неправильно, приведенный выше код не позволит вам впоследствии его изменить. –

+0

Я отредактировал свой ответ и предложил другой подход. Протестировано только строковыми значениями в виде комбо-элементов, но вы получите это. – Nino

1

Вот подход можно взять.

  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:

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

Иногда при проверке, как это, вам необходимо предотвратить выполнение логики проверки, если пользователь нажимает кнопку «Отмена». Вы должны установить для свойства CausesValidation кнопку «Отмена» значение «ложно», чтобы предотвратить это, но я считаю, что это не работает для меня.

Вместо этого, я просто использовать bool cancelling поле, которое я поставил истина в обработчике кнопки Отмена:

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

bool cancelling; 

А затем добавьте следующие строки в начале GroupBox1_Validating():

if (cancelling) 
    return; 
0

Если это возможно, имеет другой дизайн пользовательского интерфейса, тогда мое предложение выглядит следующим образом:

Альтернативный дизайн пользовательского интерфейса - A

  1. Создать один ListBox ListFieldsOriginal и заполнить
  2. Создать второй ListBox ListUserSelection, держать его пустым первоначально
  3. Обеспечить кнопки в разделе:

    Кнопка '>' означает добавить выбранный элемент из ListFieldsOrginial в ListUserSelection на конец; и удалить этот элемент из спискаFieldsOriginal

    Кнопка '<' означает удаление выбранного точного элемента из lstUserSelection; и добавить этот товар в ListFieldsOriginal (конечно в конце)

ПРИМЕЧАНИЕ: При добавлении элемента обратно ListFieldsOriginal ваше требование, то дополнительное кодирование требуется, чтобы найти свой соответствующий индекс в ListFieldsOriginal.

Alternative UI Design - B

  1. Создать один CheckedListBox ListFieldsOriginal и заполнить
  2. Создать один ListBox ListUserSelection, держать его пустым первоначально
  3. Определить обработчик события ItemCheck для ListFieldsOriginal, чтобы добавить/удалить элементы в/из списка 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); 
    } 
    
Смежные вопросы