网络的方法解决不了在“创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”的问题?

时间:2021-06-25 19:44:42
我的项目上有Form1和Form2共2个窗体,Form1是主窗体,Form1上有一个公共方法deal(里面要用到Clipboard粘贴板的功能,且一定要用到this.invoke),Form1在初始化时new出一个Form2,Form2上有一个按钮Button1,点击Button1会新建线程调用Form1.deal(),此时会报出“创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke”错误。我查看了网上的解决方法是使用this.IsHandleCreated来判断,虽然不报错,但是这样不会执行Form1.deal()中this.invoke里的处理代码,而这些代码我是需要执行的。请问大家有什么解决方法?

13 个解决方案

#1


你的 Form1.deal() 是静态方法,自然是访问不到控件实例的

#2


引用 1 楼 xuzuning 的回复:
你的 Form1.deal() 是静态方法,自然是访问不到控件实例的

因为在Form2上一定要新建线程调用Form1.deal()来使用Clipboard粘贴板,所以Form1.deal()要含this.invoke。但是会出现那个提示。请问有什么解决方法?

#3


Form1.deal() 的代码如下:
public string deal()
{
string functionReturnValue = "";
lock (ClipSave) {
this.Invoke(() =>
{
string Clip = Clipboard.GetText();
functionReturnValue = Clipboard.GetText();
Clipboard.SetDataObject(Clip);
});
}
return functionReturnValue;
}

#4


你的form1已经运行在主线程了,你想在新线程中INVOKE必须要先释放,或者重新创建一个新的实例。

#5


自己画画流程图,你的流程设计的就有问题。

#6


贴出你的
“点击Button1会新建线程调用Form1.deal()”
Button1点击事件的代码?

#7


Form1在初始化时new出一个Form2,Form2上有一个按钮Button1,点击Button1会新建线程调用Form1.deal(),
->在Form1 完全Load之后再实例化Form2并在Form2中使用委托调用form1中的那个方法。

#8


题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.

#9


引用 8 楼 lescper2011 的回复:
题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。

#10


引用 9 楼 zjnuan 的回复:
Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊

#11


引用 10 楼 lescper2011 的回复:
Quote: 引用 9 楼 zjnuan 的回复:

Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊


引用 10 楼 lescper2011 的回复:
Quote: 引用 9 楼 zjnuan 的回复:

Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊


如果在工作线程里直接使用Clipboard粘贴板是不起作用的,一定要把使用Clipboard粘贴板的代码放进this.invoke里才能起作用,也就是说只能在UI线程里起作用。

#12


初始化时创建 Form2实例?应该在创建完毕 Form1 实例之后,也就是 Form1 的 Load 事件中才初始化 Form2 实例。

不要乱把代码写到窗体实例化方法中。这通常会有很多 bug。该等到 Load 事件才执行的事情就要写到事件处理过程中。

#13


另外,设计上更高级的概念,是依赖倒置基本原则,也就是说假设 Form1 依赖于 Form2,那么你的 Form2就不应该依赖于 Form1,你的 Form2里边的方法应该使用事件通知的方式来操作,而不是直接假设 Form1 存在。

Form2应该根本不知道、也不在乎 Form1 是否存在。

#1


你的 Form1.deal() 是静态方法,自然是访问不到控件实例的

#2


引用 1 楼 xuzuning 的回复:
你的 Form1.deal() 是静态方法,自然是访问不到控件实例的

因为在Form2上一定要新建线程调用Form1.deal()来使用Clipboard粘贴板,所以Form1.deal()要含this.invoke。但是会出现那个提示。请问有什么解决方法?

#3


Form1.deal() 的代码如下:
public string deal()
{
string functionReturnValue = "";
lock (ClipSave) {
this.Invoke(() =>
{
string Clip = Clipboard.GetText();
functionReturnValue = Clipboard.GetText();
Clipboard.SetDataObject(Clip);
});
}
return functionReturnValue;
}

#4


你的form1已经运行在主线程了,你想在新线程中INVOKE必须要先释放,或者重新创建一个新的实例。

#5


自己画画流程图,你的流程设计的就有问题。

#6


贴出你的
“点击Button1会新建线程调用Form1.deal()”
Button1点击事件的代码?

#7


Form1在初始化时new出一个Form2,Form2上有一个按钮Button1,点击Button1会新建线程调用Form1.deal(),
->在Form1 完全Load之后再实例化Form2并在Form2中使用委托调用form1中的那个方法。

#8


题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.

#9


引用 8 楼 lescper2011 的回复:
题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。

#10


引用 9 楼 zjnuan 的回复:
Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊

#11


引用 10 楼 lescper2011 的回复:
Quote: 引用 9 楼 zjnuan 的回复:

Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊


引用 10 楼 lescper2011 的回复:
Quote: 引用 9 楼 zjnuan 的回复:

Quote: 引用 8 楼 lescper2011 的回复:

题主你把deal方法copy到form2不就行了

如果一定要调用Form2的deal方法,那就实例化一个form2窗口,并隐藏,之后调用,再销毁Form2.


deal会用到Clipboard粘贴板,所以要放在作为UI的Form1中。新建线程如果不用this.Invoke,是不能把数据复制到Clipboard粘贴板。


你这个是啥意思?你要复制哪里的数据,剪贴板是都可以调用的啊


如果在工作线程里直接使用Clipboard粘贴板是不起作用的,一定要把使用Clipboard粘贴板的代码放进this.invoke里才能起作用,也就是说只能在UI线程里起作用。

#12


初始化时创建 Form2实例?应该在创建完毕 Form1 实例之后,也就是 Form1 的 Load 事件中才初始化 Form2 实例。

不要乱把代码写到窗体实例化方法中。这通常会有很多 bug。该等到 Load 事件才执行的事情就要写到事件处理过程中。

#13


另外,设计上更高级的概念,是依赖倒置基本原则,也就是说假设 Form1 依赖于 Form2,那么你的 Form2就不应该依赖于 Form1,你的 Form2里边的方法应该使用事件通知的方式来操作,而不是直接假设 Form1 存在。

Form2应该根本不知道、也不在乎 Form1 是否存在。