none
checkedListBox1.Items.Contains() не срабатывает RRS feed

  • Вопрос

  • Приветствую.

    Код:

                if (_furthExmTxtBox.Text != "")
                {
                    _doctorLst.AddRange(_furthExmTxtBox.Text.Split(','));
    foreach (var item in _doctorLst)
                            if (checkedListBox1.Items.Contains(item))
                                checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                }

    Contains срабатывает только если в листе одно значение. Если два и более, то условие почему-то не проходит, хотя листбокс содержит такую запись.

    Подскажите, в чем может быть проблема? Спасибо.

    11 февраля 2013 г. 13:11

Ответы

  • Если я правильно понял, то в CheckedListBox значения занесены через дизайнер(либо из базы где-то подгружаются, не суть). И заносятся они туда в таком виде: "ФЛГ", "ЭКГ", "AAA", "BBB", "CCC".... А в _doctorLst попадают значения: "ФЛГ", " ЭКГ", " AAA", " BBB", " CCC". Т.е. после String.Split(',') строки(кроме первой) содержат вначале пробел, соответственно Contains() их и не находит.

    Попробуйте такой вариант:

    var lb = new CheckedListBox();
                var doctorLst = new List<string>();
                var text = "ФЛГ, ЭКГ";
                lb.Items.AddRange(new string[] { "ФЛГ", "ЭКГ" });
                doctorLst.AddRange(text.Split(new []{',',' '}, StringSplitOptions.RemoveEmptyEntries));
    
                foreach (var item in doctorLst) {
                    if (lb.Items.Contains(item))
                        lb.SetItemChecked(lb.Items.IndexOf(item), true);
                }

    • Изменено Varlamov Oleg 17 февраля 2013 г. 13:20
    • Помечено в качестве ответа Geokish 17 февраля 2013 г. 14:00
    17 февраля 2013 г. 13:14
  • Вот пример который работает.
    • Помечено в качестве ответа Geokish 17 февраля 2013 г. 14:00
    17 февраля 2013 г. 13:17

Все ответы

  • Чтобы метод Contains(item) корректно отрабатывал, вы должны понимать, что item в _doctorLst должен указывать на один и тот же объект что и item из checkedListBox1. 
     То есть в вашем примере если вы добавляете в списки просто строки как объекты, то и искать вам нужно сторки а не объекты, как это делает метод Contains(item). 

    11 февраля 2013 г. 13:42
  • Да, в List у меня находятся строки. Каким образом тогда надо исправить, чтобы оно искало строки?

    Спасибо.

    11 февраля 2013 г. 15:18
  • Исправил на конструкцию такого вида:

                     foreach (var item in _doctorLst)
                     {
                         checkedListBox1.SetItemChecked(checkedListBox1.FindStringExact(item), true);
                     }

    Но все равно второй элемент не хочет искать.

    11 февраля 2013 г. 15:55
  • А вы уверены что у вас в этом проблема?

    1. Что так:

    if (!String.IsNullOrEmpty(_furthExmTxtBox.Text))
                {
                    _doctorLst.AddRange(_furthExmTxtBox.Text.Split(','));
    
                    foreach (var item in _doctorLst)
                    {
                        if (checkedListBox1.Items.Contains(item))
                        {
                            checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                        }
                        else
                        {
                            checkedListBox1.Items.Add(item);
                        }
                    }
                }

    2. Что так:

                checkedListBox1.Items.Add("1");
                checkedListBox1.Items.Add("2");
                checkedListBox1.Items.Add("3");
                checkedListBox1.Items.Add("4");
                checkedListBox1.Items.Add("5");
    
                if (!String.IsNullOrEmpty(_furthExmTxtBox.Text))
                {
                    // Введен текст "3,5"
                    _doctorLst.AddRange(_furthExmTxtBox.Text.Split(','));
    
                    foreach (var item in _doctorLst)
                    {
                        if (checkedListBox1.Items.Contains(item))
                        {
                            checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                        }
                    }
                }

    У меня строки находятся в обоих случаях...

    Вы можете привести свой полный код?

    11 февраля 2013 г. 16:37
  • Пожалуйста. Вот код формы:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class FurtherExam : Form
        {
            private readonly List<string> _doctorLst = new List<string>();
            private readonly TextBox _furthExmTxtBox;
    
            public FurtherExam(TextBox furthExmTxtBox)
            {
                InitializeComponent();
                _furthExmTxtBox = furthExmTxtBox;
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                _doctorLst.AddRange(checkedListBox1.CheckedItems.OfType<string>());
                _furthExmTxtBox.Clear();
                _doctorLst.ForEach(item =>
                { _furthExmTxtBox.Text += _doctorLst.IndexOf(item) == _doctorLst.Count - 1 ? item : item + ", "; });
                Close();
            }
    
            private void FurtherExam_Load(object sender, EventArgs e)
            {
                if (String.IsNullOrEmpty(_furthExmTxtBox.Text)) return;
                _doctorLst.AddRange(_furthExmTxtBox.Text.Split(','));
                foreach (var item in _doctorLst)
                {
                    if (checkedListBox1.Items.Contains(item))
                        checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                }
            }
        }
    }

    11 февраля 2013 г. 17:01
  • Если для этой формы в список checkedListBox1 предварительно добавить элементы, то у меня все работает. Хотя с другой стороны ваш код странноват. Для чего вы в конструктор формы передаете TextBox? Можно же просто передать список LIst<T>.

    И собственно цель какая? Что должна делать программа?

    11 февраля 2013 г. 17:41
  • Я заметил, что если этот код использовать как у меня в Form_Load, то он не работает. А если, например, в Button_Click, то все проходит.

    Цель такая: из одной формы передать содержимое textBox в другую форму, распарсить (убрать разделитель) и в checkedListBox отметить те значения, которые были в textBox.

    11 февраля 2013 г. 17:49
  • а в checkedListBox значения откуда появляются?
    11 февраля 2013 г. 18:01
  • Всё. Готово. Разобрался. Я передал в конструктор еще и список, сформированный в предыдущей форме:

        public partial class FurtherExam : Form
        {
            private readonly List<string> _doctorLst = new List<string>();
            private readonly TextBox _furthExmTxtBox;
    
            public FurtherExam(TextBox furthExmTxtBox, List<string> lst)
            {
                InitializeComponent();
                _furthExmTxtBox = furthExmTxtBox;
                _doctorLst = lst;
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                Close();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                _doctorLst.Clear();
                _furthExmTxtBox.Clear();
                _doctorLst.AddRange(checkedListBox1.CheckedItems.OfType<string>());
                _doctorLst.ForEach(item =>
                { _furthExmTxtBox.Text += _doctorLst.IndexOf(item) == _doctorLst.Count - 1 ? item : item + ", "; });
                Close();
            }
    
            private void FurtherExam_Load(object sender, EventArgs e)
            {
                if (String.IsNullOrEmpty(_furthExmTxtBox.Text)) return;
                _doctorLst.ForEach(item =>
                    {
                        if (checkedListBox1.Items.Contains(item))
                            checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                    });
            }
        }
    • Помечено в качестве ответа Geokish 11 февраля 2013 г. 18:19
    • Снята пометка об ответе Geokish 17 февраля 2013 г. 7:45
    11 февраля 2013 г. 18:19
  • Приветствую.

    Рано я начал радоваться :) Приведенный выше код работает, если в только что открытой форме добавить данные в TextBox. А если, например, эти данные попадают из другой формы, то код уже не работает. Чтобы было понятен принцип работы моего "оконного приложения" привожу цепочку открытия окон: Главное окно (в нем dataGridView) -> из datagridview данные загружаются в поля второй формы (я передаю в конструктор формы datagridview из главной формы) -> из текстового поля второй формы данные вынимаются и отправляются в третью форму, где нужно отметить нужные пункты в checkedListBox. Код этуго пути такой:

    private readonly DataGridView _dataGridView;
    private readonly List<string> _furtherExamLst = new List<string>();
    
    public EditPerson(DataGridView dataGridView)
    {
        InitializeComponent();
        _dataGridView = dataGridView;
    }
    
    //По клику на поле открываем 3-ю форму
    private void textBox11_Click(object sender, EventArgs e)
    {
        if (!String.IsNullOrEmpty(textBox11.Text))
            _furtherExamLst.AddRange(textBox11.Text.Split(','));
    
        FurtherExam furtherExam = new FurtherExam(textBox11, _furtherExamLst);
        furtherExam.ShowDialog();
    }

    Код для 3-ей формы:

    public partial class FurtherExam : Form
    {
        private readonly List<string> _furtherExamLst = new List<string>();
        private readonly TextBox _furthExmTxtBox;
    
        public FurtherExam(TextBox furthExmTxtBox, List<string> lst)
        {
            InitializeComponent();
            _furthExmTxtBox = furthExmTxtBox;
            _furtherExamLst = lst;
        }
    
    private void button2_Click(object sender, EventArgs e)
    {
        Close();
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
        _furtherExamLst.Clear();
        _furthExmTxtBox.Clear();
                _furtherExamLst.AddRange(checkedListBox1.CheckedItems.OfType<string>());
                _furtherExamLst.ForEach(item =>
                { _furthExmTxtBox.Text += _furtherExamLst.IndexOf(item) == _furtherExamLst.Count - 1 ? item : item + ", "; });
        Close();
    }
    
    private void FurtherExam_Load(object sender, EventArgs e)
    {
        if (String.IsNullOrEmpty(_furthExmTxtBox.Text)) return;
        _furtherExamLst.ForEach(item =>
                    {
                        if (checkedListBox1.Items.Contains(item))
                            checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);
                    });
    }
    }

    Визуально это выглядит таким образом:

    В поле Дообследование два значения, а в открытой 3-ей форме отмечено всего одно. Подскажите, пожалуйста.

    Спасибо.

    17 февраля 2013 г. 8:03
  • Я не понимаю зачем вы передаете в качестве параметров элементы управления? Это совсем не красиво! Можно просто передавать и получать списки элементов.
    17 февраля 2013 г. 11:54
  • Можно просто передавать и получать списки элементов.
    Не совсем понял, что вы имеете ввиду? Списки контролов или значения в этих контролах в виде списка?
    17 февраля 2013 г. 12:08
  • Значения в виде списка строк.
    17 февраля 2013 г. 12:35
  • Хорошо. Я переделаю, но ведь это не решит проблему. Не срабатывает эта часть кода:

    if (checkedListBox1.Items.Contains(item))

    на втором значении из списка оно просто игнорируется и в условие не попадает. Может это связано с Form_Load? Помогите, пожалуйста. Очень надо решить данную проблему.

    Спасибо.

    17 февраля 2013 г. 12:39
  • Если я правильно понял, то в CheckedListBox значения занесены через дизайнер(либо из базы где-то подгружаются, не суть). И заносятся они туда в таком виде: "ФЛГ", "ЭКГ", "AAA", "BBB", "CCC".... А в _doctorLst попадают значения: "ФЛГ", " ЭКГ", " AAA", " BBB", " CCC". Т.е. после String.Split(',') строки(кроме первой) содержат вначале пробел, соответственно Contains() их и не находит.

    Попробуйте такой вариант:

    var lb = new CheckedListBox();
                var doctorLst = new List<string>();
                var text = "ФЛГ, ЭКГ";
                lb.Items.AddRange(new string[] { "ФЛГ", "ЭКГ" });
                doctorLst.AddRange(text.Split(new []{',',' '}, StringSplitOptions.RemoveEmptyEntries));
    
                foreach (var item in doctorLst) {
                    if (lb.Items.Contains(item))
                        lb.SetItemChecked(lb.Items.IndexOf(item), true);
                }

    • Изменено Varlamov Oleg 17 февраля 2013 г. 13:20
    • Помечено в качестве ответа Geokish 17 февраля 2013 г. 14:00
    17 февраля 2013 г. 13:14
  • Вот пример который работает.
    • Помечено в качестве ответа Geokish 17 февраля 2013 г. 14:00
    17 февраля 2013 г. 13:17
  • ГЕНИАЛЬНО!

    Спасибо вам большое! У меня реально сломалась голова уже.

    17 февраля 2013 г. 14:00
  • Спасибо за помощь!
    17 февраля 2013 г. 14:00