none
How to create new TabPages from a Thread RRS feed

  • Question

  • Hi,


    I 've got a Problem.
    I simply have got a Thread running and when something happens a new Tab should be created in a Form.
    When I call the Method for creating a new TabPage from from the Tread I allways get the following Exception:

    Controls created on one thread cannot be parented to a control on a different thread.

    So can anybody say me, how I have to call the method correctly???
    Or maybe a small tutorial how to create new Tabs from a running Thread.








    Saturday, December 8, 2007 10:39 AM

Answers

  • The exception says it all, you can't create a control on one thread (especially a non GUI thread) and make the control the child of another control/form that was created in another thread.

     

    In order to methods and properties on a control/form you must use Control.Invoke/.BeginInvoke

     

    The easiest thing to do is to have a method on your form class that checks Control.InvokeRequired and calls Control.BeginInvoke.  For example:

     

            private void AddTab ( )

            {

                if (this.InvokeRequired)

                {

                    this.BeginInvoke(delegate

                    {

                        AddTab();

                    });

                }

                else

                {

                    // create the tab

                    CreateTabControl();

                }

            }

     

    You could then call AddTab from any thread and have it work...
    Saturday, December 8, 2007 1:21 PM
  • YYYeah!!! Thanx




    For them who have got the same problem I solved it like this:

    - in the form where the new tab should be created, I've made a delegate class
    public delegate void tchange(String em);  <-- has no body there for ";"

    - them , for making it all work I've asked Mr. Google for help me with delegate
       when you have created smothing like above you can "add" classes to that delegate
       they can then be called

     private void TestMethod(String mailToCreate)
            {
                String TabName = somename;
                TabPage NewTab = new TabPage(somename);
                NewTab.Controls.Add(help1);
                BuddyWins.Add(partnermail.ToLower(), help1);
                help1.Name = partnermail;
                test.tabControl1.TabPages.Add(NewTab);// test = the control of the gui class
            }

    - and when that method to create the tab is made it has to be called. I made it like in the post above from Peter Ritchie
    i looks like that

    public void AddTab()
            {

                if (this.InvokeRequired)
                {


                    this.BeginInvoke(new tchange(TestMethod),"somestring);
                   
                }

                else
                {
                   // CreateTabControl();
                }

            }
    you see the method which is connected to the delegate is called if Invoke is required

    all thre steps I mentioned are to make in the Form where the Tab is to create

    - the last step is only to call the method addTab from the Tread. You must have a reference of the Form Object in the
         Thread. So you only give it with the thread when it is created






    Saturday, December 8, 2007 2:40 PM

All replies

  • The exception says it all, you can't create a control on one thread (especially a non GUI thread) and make the control the child of another control/form that was created in another thread.

     

    In order to methods and properties on a control/form you must use Control.Invoke/.BeginInvoke

     

    The easiest thing to do is to have a method on your form class that checks Control.InvokeRequired and calls Control.BeginInvoke.  For example:

     

            private void AddTab ( )

            {

                if (this.InvokeRequired)

                {

                    this.BeginInvoke(delegate

                    {

                        AddTab();

                    });

                }

                else

                {

                    // create the tab

                    CreateTabControl();

                }

            }

     

    You could then call AddTab from any thread and have it work...
    Saturday, December 8, 2007 1:21 PM
  • How does that then work with the delegate???


    Do I have to make something else, or should this code work how you posted???
    Saturday, December 8, 2007 2:07 PM
  • YYYeah!!! Thanx




    For them who have got the same problem I solved it like this:

    - in the form where the new tab should be created, I've made a delegate class
    public delegate void tchange(String em);  <-- has no body there for ";"

    - them , for making it all work I've asked Mr. Google for help me with delegate
       when you have created smothing like above you can "add" classes to that delegate
       they can then be called

     private void TestMethod(String mailToCreate)
            {
                String TabName = somename;
                TabPage NewTab = new TabPage(somename);
                NewTab.Controls.Add(help1);
                BuddyWins.Add(partnermail.ToLower(), help1);
                help1.Name = partnermail;
                test.tabControl1.TabPages.Add(NewTab);// test = the control of the gui class
            }

    - and when that method to create the tab is made it has to be called. I made it like in the post above from Peter Ritchie
    i looks like that

    public void AddTab()
            {

                if (this.InvokeRequired)
                {


                    this.BeginInvoke(new tchange(TestMethod),"somestring);
                   
                }

                else
                {
                   // CreateTabControl();
                }

            }
    you see the method which is connected to the delegate is called if Invoke is required

    all thre steps I mentioned are to make in the Form where the Tab is to create

    - the last step is only to call the method addTab from the Tread. You must have a reference of the Form Object in the
         Thread. So you only give it with the thread when it is created






    Saturday, December 8, 2007 2:40 PM
  • The sample I provided use an anonymous method (that just recursively calls the method).  Yes, you could create a new delegate (or use Action<T>/MethodInvoker); but then you have a bunch of code that isn't really needed if all you want to do is make sure a method is run on the Control's/Form's thread...

     

    Saturday, December 8, 2007 3:27 PM