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

    Question

  • Hi all,

    I have Crystal report in my Application. To Load the Crystal Report it take some time (more than a 2 minutes). So I planned to Load the crystal report in the ASync mode. I have used the MethodInvoker object and BackgroundWorker components.

    It works properly but when i try to access the Crystal report i'm getting the below error:

     

    An exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll but was not handled in user code

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

     

    Initial i get this error whiling accesssing the windows control. I overcome this error by adding code:

     

    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

     

    But now i have issue while accessing the Crystal Report.

     

    Thanks & regards,

     

    Tuesday, April 24, 2007 6:35 AM

All replies

  • Hi Tamil,

    Study this example :

        public partial class Form8 : Form
        {
            public Form8()
            {
                InitializeComponent();

                // Test out four methods to change a control's text property from other thread.
                new Thread(new ThreadStart(ChangeText1)).Start();
                new Thread(new ThreadStart(ChangeText2)).Start();
                new Thread(new ThreadStart(ChangeText3)).Start();
                new Thread(new ThreadStart(ChangeText4)).Start();
            }

            delegate void VoidDelegate();
            delegate void ChangeControlTextDelegate(Control ctrl, string txt);

            private void ChangeText1()
            {
                // Simply use form's Invoke() method to invoke the anonymous method to set form's text in form's thread
                Thread.Sleep(1000);
                Invoke(new VoidDelegate(delegate() { Text = "Some Text 1"; }));
            }

            private void ChangeText2()
            {
                // Create a delegate to store a method (ChangeControlText()) reference and
                // use form's Invoke() to invoke it in the form's thread. Arguments are passed
                // to Invoke() as 'params object array'.
                ChangeControlTextDelegate d = new ChangeControlTextDelegate(ChangeControlText);
                Thread.Sleep(2000);
                Invoke(d, this, "Some Text 2");
            }

            private void ChangeText3()
            {
                // Here, we check if this method is called from the thread other than the one created form.
                // If cross-thread call, use invoke, otherwise directly call ChangeControlText()
                if (InvokeRequired)
                {
                    ChangeControlTextDelegate d = new ChangeControlTextDelegate(ChangeControlText);
                    Thread.Sleep(3000);
                    Invoke(d, this, "Some Text 3");
                }
                else
                {
                    Thread.Sleep(3000);
                    ChangeControlText(this, "Some Text 3");
                }
            }

            private void ChangeText4()
            {
                // Here, we directly call ChangeControlText2(), It handles cross-thread call checks on it's own.
                Thread.Sleep(4000);
                ChangeControlText2(this, "Some Text 4");
            }

            // This method just sets given control's text property to given string
            private void ChangeControlText(Control ctrl, string txt)
            {
                ctrl.Text = txt;
            }

            // This is a tricky method.
            // If it is called from other thread, it will go into if block, and call itself from control's thread.
            // And that call will go into else block.
            // Otherwise it will directly go into else block.
            private void ChangeControlText2(Control ctrl, string txt)
            {
                // This function handles cross-thread call checks itself and changes
                // control's text property accordingly.
                if (ctrl.InvokeRequired)
                {
                    ChangeControlTextDelegate d = new ChangeControlTextDelegate(ChangeControlText2);
                    ctrl.Invoke(d, ctrl, txt);
                }
                else
                {
                    ctrl.Text = txt;
                }
            }
        }

    Also study Control.InvokeRequired Property and Control.Invoke() method.
    Tuesday, April 24, 2007 9:27 AM
  • Thanks for you reply.

     

    It is working fine for Windows control. But when i use the Same Coding for Crystal Report control , I'm getting the below Error:

     

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

     

    Waiting for reply.
    Tuesday, April 24, 2007 9:54 AM
  • Can I have some code?
    Tuesday, April 24, 2007 1:39 PM
  • Move from Windows Forms General to Crystal Report For Visual Studio for better responses.
    Monday, April 30, 2007 9:19 AM
  • Thank you.

     

    Waiting for reply

    Wednesday, May 02, 2007 6:21 AM