locked
How to attach a Control created in a new Thread to the Main Thread(Form thread)? RRS feed

  • Question

  • hi guys,
    suppose i have one win app and Form1.
    suppose i create a new Thread and In there i want to access SQL SErver and bring a result of my query into DataTable object( dt ).
    and also suppose i create a DataGridView Control and attach the dt to its DataSource proerty.now
    i want to place this datagridview to my main form(Form1).
    how should i do that?



    Brainstorm your Brain and find solution,if no result stuck to Brainstormer.
    • Edited by simosi Thursday, July 31, 2008 6:26 AM Completed
    Thursday, July 31, 2008 6:16 AM

Answers

  • If i am not wrong then wat i understood is this :
    You create a new thread in which you retrieve some data from database and populate the datatable.
    Then in same thread you create an instance of data gridview and assign the data
    populated in datatable to it.
    Now you want to show this datagridview in the form.
    If this is wat u meant then check out the following :

    public partial class Form1 : Form{ 
           private delegate void SetDataGridViewDelegate (DataGridView dgv); 
           private Thread t = null
     
           private void SetDataGridView(DataGridView dgv) { 
                if (this.InvokeRequired) 
                { 
                    SetDataGridViewDelegate d = new SetDataGridViewDelegate(SetDataGridView); 
                    this.Invoke(d, dgv); 
                } 
                else { 
                    dgv.Location = new Point(0, 0); 
                    dgv.Width = 200
                    dgv.Height = 100
                    this.Controls.Add(dgv); 
                } 
            } 
             
            public Form1() 
            { 
                InitializeComponent(); 
                t = new Thread(new ThreadStart(thread)); 
            } 
     
            private void thread() 
            { 
                DataSet ds1 = new DataSet(); 
                try 
                { 
                    // populate DataSet 
     
                } 
                catch (SqlException sqex) 
                { 
                    MessageBox.Show("Error " + sqex); 
                } 
                catch (Exception ex) 
                { 
                    MessageBox.Show("Error " + ex); 
                } 
                finally 
                { 
                     // close connection 
                } 
       
                DataGridView dgv = new DataGridView(); 
                dgv.DataSource = ds1.Tables[0]; 
                SetDataGridView(dgv); 
            } 
     
            private void Form1_Load(object sender, EventArgs e) 
            { 
                t.Start(); 
                //dataGridView1.DataSource = LoadDataSet().Tables[0]; 
            } 
     
     
        } 
     
     

    hope this works for u

    Wife is like a Software, Lots of bugs.
    Thursday, July 31, 2008 7:44 AM
  • You cannot create a DataGridView control in one thread and add it to a form in another thread.  Cannot access a control from a thread another than the one it was created on or you will get an exception.  You need to use the InvokeRequired property to see if the current thread is the same as thread the control was created on and the invoke method which will execute a delegate on the thread a control was created on.

            public void SetData(object data)
            {
                if (!InvokeRequired)
                {
                    DataGridView view = new DataGridView();
                    view.DataSource = data;
                    this.Controls.Add(view);
                    return;
                }

                Invoke(delegate(object o) { SetData(o); }, new object[] { data });
                return;

            }

    You should probably use a backgroundworker class.  Just drag it from the toolbar onto your form.  Add event handlers for DoWork and RunWorkerCompleted.  Start the background worker with the RunWorkAsync method.

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                DataTable dt = GetData();
                e.Result = dt;
            }
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                dataGridView1.DataSource = e.Result;
            }




    Thursday, July 31, 2008 7:55 AM

All replies

  • If i am not wrong then wat i understood is this :
    You create a new thread in which you retrieve some data from database and populate the datatable.
    Then in same thread you create an instance of data gridview and assign the data
    populated in datatable to it.
    Now you want to show this datagridview in the form.
    If this is wat u meant then check out the following :

    public partial class Form1 : Form{ 
           private delegate void SetDataGridViewDelegate (DataGridView dgv); 
           private Thread t = null
     
           private void SetDataGridView(DataGridView dgv) { 
                if (this.InvokeRequired) 
                { 
                    SetDataGridViewDelegate d = new SetDataGridViewDelegate(SetDataGridView); 
                    this.Invoke(d, dgv); 
                } 
                else { 
                    dgv.Location = new Point(0, 0); 
                    dgv.Width = 200
                    dgv.Height = 100
                    this.Controls.Add(dgv); 
                } 
            } 
             
            public Form1() 
            { 
                InitializeComponent(); 
                t = new Thread(new ThreadStart(thread)); 
            } 
     
            private void thread() 
            { 
                DataSet ds1 = new DataSet(); 
                try 
                { 
                    // populate DataSet 
     
                } 
                catch (SqlException sqex) 
                { 
                    MessageBox.Show("Error " + sqex); 
                } 
                catch (Exception ex) 
                { 
                    MessageBox.Show("Error " + ex); 
                } 
                finally 
                { 
                     // close connection 
                } 
       
                DataGridView dgv = new DataGridView(); 
                dgv.DataSource = ds1.Tables[0]; 
                SetDataGridView(dgv); 
            } 
     
            private void Form1_Load(object sender, EventArgs e) 
            { 
                t.Start(); 
                //dataGridView1.DataSource = LoadDataSet().Tables[0]; 
            } 
     
     
        } 
     
     

    hope this works for u

    Wife is like a Software, Lots of bugs.
    Thursday, July 31, 2008 7:44 AM
  • You cannot create a DataGridView control in one thread and add it to a form in another thread.  Cannot access a control from a thread another than the one it was created on or you will get an exception.  You need to use the InvokeRequired property to see if the current thread is the same as thread the control was created on and the invoke method which will execute a delegate on the thread a control was created on.

            public void SetData(object data)
            {
                if (!InvokeRequired)
                {
                    DataGridView view = new DataGridView();
                    view.DataSource = data;
                    this.Controls.Add(view);
                    return;
                }

                Invoke(delegate(object o) { SetData(o); }, new object[] { data });
                return;

            }

    You should probably use a backgroundworker class.  Just drag it from the toolbar onto your form.  Add event handlers for DoWork and RunWorkerCompleted.  Start the background worker with the RunWorkAsync method.

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                DataTable dt = GetData();
                e.Result = dt;
            }
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                dataGridView1.DataSource = e.Result;
            }




    Thursday, July 31, 2008 7:55 AM