简体   繁体   English

如何使用Invoke或BeginInvoke方法处理Windows窗体中的控件

[英]How to use Invoke or BeginInvoke method to handle controls in windows form

I get the following exception thrown: 我抛出了以下异常:

Invoke or BeginInvoke cannot be called on a control until the window handle has been created. 在创建窗口句柄之前,无法在控件上调用Invoke或BeginInvoke。

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. 我使用的是bestlistviewer和dotnetbar,只是修改了此代码注册表清理程序,但是我试图以其他形式(而不是主要形式)调用所有类和控件。

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. System.InvalidOperationException HResult = 0x80131509 Message = Invoke或BeginInvoke不能在控件上被调用,直到创建了窗口句柄。 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.Exe Source = System.Windows.Forms StackTrace:在System.Windows.Forms.Control.MarshaledInvoke(控件调用方,Delegate方法,Object [] args,布尔同步)在System.Windows.Forms.Control.Invoke(Delegate方法,Object [ ] args),位于C:\\ Users \\ RamRo \\ source \\ repos \\ GeekVersion1 \\ GeekCleaner \\ GeekCleaner \\ RegistryScan中的GeekCleaner.Registry_Scan.GeekOnScanComplete(List`1&_GeekListOfGroupTargets)中的System.Windows.Forms.Control.Invoke(委托方法)。 C:\\ Users \\ RamRo \\ source \\ repos \\ GeekVersion1 \\ GeekCleaner \\ GeekCleaner \\ UserPanel \\ StartScanning.cs中GeekCleaner.UserPanel.StartScanning.GeekStartScanning()的第34行:System.Threading.ThreadHelper.ThreadStart_Context(对象状态的第139行) )在System.Threading.Exe处位于System.Threading.ExecutionContext.Run(ExecutionContext执行上下文,ContextCallback回调,对象状态,布尔状态保持同步Ctx)在System.Threading.ExecutionContext.RunInternal(ExecutionContext执行上下文,ContextCallback回调,对象状态,布尔值保持SyncCtx) cutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() 在System.Threading.ThreadHelper.ThreadStart()处的cutionContext.Run(ExecutionContext executeContext,ContextCallback回调,对象状态)

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. 只需在InitializeComponent调用之前调用Invoke,即可在非常简单的应用程序中轻松重现该异常。

Since all your shown code looks synchronous and is beyond Registry_Scan's InitializeComponent I don't think the problem is there. 由于您显示的所有代码看起来都是同步的,并且超出了Registry_Scan的InitializeComponent,所以我认为问题不存在。

So you should check StartScanning.GeekCreateControl() and other calls for possible multitasking issue which will trigger an Invoke before InitializeComponent like this one: 因此,您应该检查StartScanning.GeekCreateControl()和其他调用是否存在多任务问题,这些问题将在InitializeComponent之前触发一个Invoke,如下所示:

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

        InitializeComponent();
    }
}

Hope this helps 希望这可以帮助

I think there is InvokeRequired property for checking if the form need invoke or not? 我认为这里有InvokeRequired属性,用于检查表单是否需要调用?

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM