【问题标题】:Invoke or BeginInvoke cannot be called on a control... even using CreateControl()不能在控件上调用 Invoke 或 BeginInvoke...即使使用 CreateControl()
【发布时间】:2018-12-28 08:05:41
【问题描述】:

我无法从我的 Form1 修改属于 Form 2 的元素。

public partial class Project : Form
{
    public Form2 form = new Form2();

    public Project()
    {
        InitializeComponent();
    }

    private void Project_Load(object sender, EventArgs e)
    {
        form.CreateControl();
    }

    private void buttonOpenForm2_Click(object sender, EventArgs e)
    {
        form.Show();
    }

    private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
    {
        var indata = *whatever serial input data here*
        bool result = Int32.TryParse(indata, out int data);

        if (result) {
        form.chart1.Invoke(new Action(() => { form.chart1.Series[0].Points.AddY(data); }));
        }
    }

每当我按下按钮以显示 Form2 及其图表时,form.chart1.Invoke:Invoke or BeginInvoke cannot be called on a control until the window handle has been created. 中都会引发异常

如果我强制form 执行CreateControl(),为什么会发生这种情况?

【问题讨论】:

  • Windows 窗体在后台使用 Windows User32、Gdi32 和其他传统 Windows 库。当您实例化一个 Form 对象时,您为 Windows 窗口创建了一个空心包装器。当您显示表单时,一个复杂的舞蹈开始了,有一次调用传统的 Windows Create 函数来创建窗口(以及窗口的窗口句柄)。在那之前,有些事情是你不能做的。因此,直到您的 Form2 完全完成自我创建(它肯定由 Form.Load 事件完成)之前,您不能 Invoke 表单上的任何内容

标签: c# invoke


【解决方案1】:

错误信息告诉你出了什么问题。

您的串行端口在 form2(保存您的图表)完全创建之前触发

我猜你可以检查可见标志(可能还有很多其他标志)

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{

   ...

   if(!form?.Visible)
      return;

   form.chart1.Invoke(...

假设如果它不可见,你就不想显示数据


进一步阅读

Order of Events in Windows Forms

应用程序启动和关闭事件

Form 和 Control 类公开了一组与 应用程序启动和关闭。当一个 Windows 窗体应用程序 开始,主窗体的启动事件在 以下顺序:

Control.HandleCreated

Control.BindingContextChanged

Form.Load

Control.VisibleChanged

Form.Activated

Form.Shown

【讨论】:

    猜你喜欢
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 2021-05-14
    • 1970-01-01
    • 2010-10-22
    • 1970-01-01
    相关资源
    最近更新 更多