none
данные в таблице не обнавляются на экране. RRS feed

  • Вопрос

  • есть метод(событие), который по мере поступления данных, заполняет таблицу.

            void list_ShowMessage(object sender, EventArgs e)
            {
                DataRow dr = oDt.NewRow();
                DateTime dd = DateTime.Now;
                MessageEventArgs arg = (MessageEventArgs)e;
                dr["Тип"] = arg.Category.ToString();
                dr["Дата"] = dd.ToShortDateString()+" "+dd.ToShortTimeString();
                dr["Сообщение"] = arg.message;
                oDt.Rows.Add(dr);
            }

    инициализирую все тут:

    DataTable oDt;
    
    private void Form1_Load(object sender, EventArgs e)
    {
                oDt = new DataTable();
                DataColumn dtc = new DataColumn("Тип", typeof(string));
                oDt.Columns.Add(dtc);
                dtc = new DataColumn("Дата", typeof(string));
                oDt.Columns.Add(dtc);
                dtc = new DataColumn("Сообщение", typeof(string));
                oDt.Columns.Add(dtc);
                dataGridView1.DataSource = oDt;
     и т.д.
    }

    данные поступают, таблица заполняется, но в контроле можно их увидеть, если потыкать мышкой, или двигать ч/з scroll.

    пробовал только контрол обновить ч/з Refresh(). получаю ошибку:

      Message "Недопустимая операция в нескольких потоках: попытка доступа к элементу управления 'dataGridView1' не из того потока, в котором он был создан." string

    как правильно сделать?


    26 марта 2012 г. 5:53

Ответы

Все ответы

  • Здравствуйте.

    Из потока нельзя обращатся напрямую к элементам управления (метод Refresh), к ним нужно обращатся только из главного UI потока. Для обращения из потока вам нужно использовать метод Invoke, смотрите статьюПрактическое руководство. Осуществление потокобезопасных вызовов элементов управления Windows Forms.


    Для связи [mail]

    • Помечено в качестве ответа anknown123455 26 марта 2012 г. 8:06
    26 марта 2012 г. 7:19
  • Спасибо за подсказку.

    Я так и понял, что нельзя напрямую..

    26 марта 2012 г. 8:06
  • > Message "Недопустимая операция в нескольких потоках ...


    т.к. DataTable привязан к DataGridView, то вызов DataTable.Rows.Add(DataRow) выполнять в основном потоке.
    пример добавления строк в DataTable из отдельного потока:
     

    using System;
    using System.ComponentModel;
    using System.Data;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                var dt = new DataTable();
                dt.Columns.Add("Тип", typeof(string));
                dt.Columns.Add("Дата", typeof(DateTime));
                dt.Columns.Add("Сообщение", typeof(string));
    
                // создать отдельный поток
                Task.Factory.StartNew(new Action<object>(Run), AsyncOperationManager.CreateOperation(dt));
    
                this.Size = new System.Drawing.Size(600, 500);
                new DataGridView { Parent = this, Dock = DockStyle.Fill, DataSource = dt, AllowUserToAddRows=false };
            }
    
            void Run(object state)
            {
                var ao = state as AsyncOperation;
                var dt = ao.UserSuppliedState as DataTable;
                SendOrPostCallback add = nr => // выполняется в потоке, в котором создан AsyncOperation
                    dt.Rows.Add((DataRow)nr);
    
                for (int i = 0; i < 1000; i++)
                {
                    var dr = dt.NewRow();
                    dr["Тип"] = "t" + i;
                    dr["Дата"] = DateTime.Now;
                    dr["Сообщение"] = "msg" + i;
                    ao.Post(add, dr);   // передать dr в основной поток
    
                    Thread.Sleep(500);  // только для теста
                }
            }
        }
    }


         
    26 марта 2012 г. 11:38