Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#使用BackGroundWorker类更新静态WinForm控件_C#_Winforms_Datagridview_Backgroundworker - Fatal编程技术网

c#使用BackGroundWorker类更新静态WinForm控件

c#使用BackGroundWorker类更新静态WinForm控件,c#,winforms,datagridview,backgroundworker,C#,Winforms,Datagridview,Backgroundworker,我有三门课: 带有按钮和面板(MyPanel)的表单类(MyForm) BackGroundWorker类(DataGridViewLoader) DataGridView类(MyDataGridView) 我选择三个独立类的原因是为了防止表单类中的代码过多 在我的表单类中,我想启动BackGroundWorker,它应该创建并填充我的DataGridView。一旦完成,它应该将我的DataGridView实例添加到我的面板中 鉴于我仍在学习编码,我有几个问题: 这可能吗 这是最好的还是最优雅的

我有三门课:

  • 带有按钮和面板(MyPanel)的表单类(MyForm)
  • BackGroundWorker类(DataGridViewLoader)
  • DataGridView类(MyDataGridView)
  • 我选择三个独立类的原因是为了防止表单类中的代码过多

    在我的表单类中,我想启动BackGroundWorker,它应该创建并填充我的DataGridView。一旦完成,它应该将我的DataGridView实例添加到我的面板中

    鉴于我仍在学习编码,我有几个问题:

  • 这可能吗
  • 这是最好的还是最优雅的方式
  • 如果这是最好的方法,那么如何将DataGridView添加到(静态)面板
  • 如果这不是最好的方法,我应该如何处理
  • 这就是我目前的情况:

    MyForm类中的代码:

    private void Button_Click(object sender, EventArgs e)
    {
        DataGridViewLoader worker = new DataGridViewLoader();
        worker.RunWorkerAsync();
    }
    
    DataGridViewLoader类中的代码:

    private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {    
         MyDataGridView myDataGridView = new MyDataGridView();
         BindingSource myBindingSource = new BindingSource();       
         myBindingSource.ResetBindings(true);
         myBindingSource.DataSource = MyDataTable;
    }
    
    看到MyPanel是静态的,我在发布的其他问题中看到需要使用invoke

    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MyForm.myPanel.Invoke(new Action(() =>
        {
             //Add datagridview to my panel.
             MyForm.myPanel.Add(myDataGridView);        
    
        }));
    }
    
    然而,我面临着这个错误:

    "An object reference is required for the non-static field, method, or property 'MyForm.myPanel'"
    

    您无法从
    BackgroundWorker
    访问GUI元素(
    DataGrid
    ),因此这是不可能的。但是您得到的编译器错误是另一回事。@jdweng,请参阅-OP在
    DoWork
    处理程序中创建一个
    DataGrid
    。这不行。请在运行BGW之前创建DGV。在
    DoWork
    中,生成一个数据表。将数据表作为
    DoWorkEventArgs].Result(
    e.Result
    返回。在
    RunWorkerCompleted
    事件中,检查
    e.Error
    e.Cancelled
    ,然后将
    e.Result
    (类型
    对象
    )作为
    数据表
    (强制转换),并将其分配给DGV的数据源(或支持绑定源)。在UI线程中引发
    RunWorkerCompleted
    事件,您不需要
    调用那里的任何内容。不确定什么是静态面板。如果您是指声明为
    静态的类,则不要。当BGW完成其工作后,您可以将此工作的结果传递给
    e.Result
    属性。此属性的值可以读取为
    RunWorkerCompleted
    事件的值(请参见此处的备注部分)。这同样适用于
    RunWorkerAsync(Object)
    重载,其中传递给该方法的
    对象成为
    dowworkeventargs.Arguments
    对象。这就是如何将值从UI线程传递到后台线程,反之亦然。您的
    DataGridViewLoader
    是一个BackGroundWorker(
    DataGridViewLoader worker=new DataGridViewLoader();worker.RunWorkerAsync();
    )。此类已初始化,并在
    按钮中使用。因此,从主UI(STA)线程单击事件处理程序。
    RunWorkerCompleted
    事件始终在调用
    RunWorkerAsync()
    的线程中引发。如果您是从另一个线程运行此表单,那么您犯了一个需要更正的错误。