[C# + WinForm] Ошибка установки данных в Combo-box с List'a

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by stas1kus, 29 Mar 2014.

  1. stas1kus

    stas1kus New Member

    Joined:
    25 Jun 2012
    Messages:
    33
    Likes Received:
    4
    Reputations:
    0
    Доброго времени суток.
    Хотел попросить помощи в решении ошибки установки данных в Combo-box в WinForm'e, которые я получил с Combo-box'a сайта. Вся суть в том, что данные с сайта я спарсил, запихнул в List, но установить не могу, т.к. вылетает ошибка "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления "combo-box" не из того потока, в котором он был создан."

    Но что еще интересно и ставит меня в тупик, я вручную запихиваю в List данные, а потом при нажатии на кнопку - данные отображаются.

    Code:
    public class ComboItem
    {
       public string Name { get; set; }
       public int Id { get; set; }
       public ComboItem(string text, int value)
       {
           Name = text;
           Id = value;
       }
    }
    
    private void button3_Click(object sender, EventArgs e)
    {
        List<ComboItem> items = new List<ComboItem>();
        BindingSource bs = new BindingSource();
        items.Add(new ComboItem("John", 1));
    
        bs.DataSource = items;
        cb_category.DataSource = bs.DataSource;
        cb_category.DisplayMember = "Name";
        cb_category.ValueMember = "Id";
    }
    
    А если данные в List ставлю динамически - ошибка

    Code:
    public class ComboItem
    {
       public string Name { get; set; }
       public int Id { get; set; }
       public ComboItem(string text, int value)
       {
          Name = text;
          Id = value;
       }
    }
    
    /*-----------MY Function--------------*/
    for (int i = 0; i < idCategory.Count-1; i++)
    {
       int num = Convert.ToInt32(idCategory[i]);
       nameCategory = SearchAndInput(dataCategory.InnerHtml, "<option value=""+num+"">", "rn");
       items.Add(new ComboItem(nameCategory[0].ToString(), num));
    }
    
    BindingSource bs = new BindingSource();
    bs.DataSource = items;
    cb_category.DataSource = bs.DataSource;
    cb_category.DataSource = items;
    cb_category.DisplayMember = "Name";
    cb_category.ValueMember = "Id";
    
    подскажите плз как правильно организовать этот 2й поток в этом случае
     
  2. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Как гласит ошибка - невозможно обратиться к потоку из другого потока напрямую. Для этого нужно использовать BackGroundWorker - вот тут очень хороший пример, когда при изменении значения, обновляется UI элемент.

    Или Делай проще - сначала спарсь и временно сохрани все значения из комбобокса, а только после того как закроешь соединение с сетью и освобдишь поток, добавляй в значение себе на форму. Для этого впринципе и не надо потоков.
    Хотя с ними и удобнее и проще.
    Вообщем кури BackGroundWorker.
     
  3. stas1kus

    stas1kus New Member

    Joined:
    25 Jun 2012
    Messages:
    33
    Likes Received:
    4
    Reputations:
    0
    Спасибо. Но решил проблему немного по другому.
    Если кто-то столкнется с подобной фигней - даю решение.

    Code:
    cb_category.BeginInvoke((Action)delegate
    {
      bs.DataSource = items;
      cb_category.DataSource = bs.DataSource;
      cb_category.DataSource = items;
      cb_category.DisplayMember = "Name";
      cb_category.ValueMember = "Id";
    });