0

I get the following exception thrown:

Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

I am using betterlistviewer and dotnetbar just modifying this code Registry cleaner but i am trying to invoke that all classes and controls in another form not in the main.

This is my code

    public Registry_Scan()
    {
        InitializeComponent();
        StartScanning GeekStartCleaning = StartScanning.GeekCreateControl();

        GeekStartCleaning.GeekOnAllScanComplete += GeekOnScanComplete;

        this.GeekPanel.Controls.Add(GeekStartCleaning);
    }
    ScanComplete GeekOnComplete = new ScanComplete();
    public void GeekOnScanComplete(ref List<BetterListViewGroup> _GeekListOfGroupTargets)
    {

        List<BetterListViewGroup> GeekListOfGroupTargets = _GeekListOfGroupTargets;

        GeekOnComplete.GeekAddRangeTargets(ref GeekListOfGroupTargets);
        GeekOnComplete.Show();
        this.GeekPanel.Invoke(new MethodInvoker(() =>
        {
            this.GeekPanel.Controls.Clear();
            this.GeekPanel.Controls.Add(GeekOnComplete);
        }));
    }

I don't know whats wrong please help

System.InvalidOperationException HResult=0x80131509 Message=Invoke or BeginInvoke cannot be called on a control until the window handle has been created. Source=System.Windows.Forms StackTrace: at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous) at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args) at System.Windows.Forms.Control.Invoke(Delegate method) at GeekCleaner.Registry_Scan.GeekOnScanComplete(List`1& _GeekListOfGroupTargets) in C:\Users\RamRo\source\repos\GeekVersion1\GeekCleaner\GeekCleaner\RegistryScan.cs:line 34 at GeekCleaner.UserPanel.StartScanning.GeekStartScanning() in C:\Users\RamRo\source\repos\GeekVersion1\GeekCleaner\GeekCleaner\UserPanel\StartScanning.cs:line 139 at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart()

Raj
  • 101
  • 1
  • 2
  • 10
  • Try BeginInvoke() instead perhaps... –  Mar 02 '18 at 04:46
  • That too not works – Raj Mar 02 '18 at 06:18
  • 2
    You probably started the thread too soon, the Load event is a good place to get it going. Or you closed the form while the thread is still running, that is bad. https://stackoverflow.com/a/1732361/17034 – Hans Passant Mar 02 '18 at 08:30
  • You are referencing a control through a method invoked when the base window is not ready (in the constructor). Move those methods to the Form.Load() or Form.Shown() events. At that point, all controls will have their own handles created. – Jimi Mar 03 '18 at 01:51
  • Can you please make some sample code on it\ – Raj Mar 03 '18 at 17:30

2 Answers2

2

I can't really tell from your code what exactly the problem is. But it will most certainly be a multitasking problem.

The Exception is easy to reproduce in a very simple Application by just calling Invoke before the InitializeComponent call.

Since all your shown code looks synchronous and is beyond Registry_Scan's InitializeComponent I don't think the problem is there.

So you should check StartScanning.GeekCreateControl() and other calls for possible multitasking issue which will trigger an Invoke before InitializeComponent like this one:

public partial class Form1 : Form
{
    public Form1()
    {
        Task.Factory.StartNew(() =>
        {
            this.Invoke(new Action(() =>
            {
                this.Text = "UI Change";
            }));
        });

        InitializeComponent();
    }
}

Hope this helps

Robin B
  • 1,066
  • 1
  • 14
  • 32
1

I think there is InvokeRequired property for checking if the form need invoke or not?

So should be like this one:

if(this.GeekPanel.InvokeRequired)
{
    this.GeekPanel.Invoke(new MethodInvoker(() =>
    {
        this.GeekPanel.Controls.Clear();
        this.GeekPanel.Controls.Add(GeekOnComplete);
    }));
}
else
{
    this.GeekPanel.Controls.Clear();
    this.GeekPanel.Controls.Add(GeekOnComplete);
}