2016-08-23 44 views
1

需要向您寻求帮助,因为我现在为此苦苦挣扎了太久。已经过去了很多教程,但还不知道呢...DataGridView窗体在后台工作完成后显示为空

在这个项目的第一阶段,我开发了一个控制台程序,向Web服务器发出请求,处理数据并更新MS Access DB。我现在的问题是,在完成所有这些处理之后,我需要在winform中显示结果以供客户端查看,而且更多的过程应该在应用程序打开时重复进行。

所以我到目前为止所做的是创建一个winform,作为后台工作者运行控制台程序,结果应该在程序继续运行时显示和更新。为简单起见,我更换所有的繁重处理只是一个循环,在哈希表的名单,这是返回的WinForm要显示填充:

namespace TheNameSpace 
{ 
    class aldeloUpdater 
    { 
     [STAThread] 
     static void Main() 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new GuiForm()); 
     } 

     public List<Hashtable> oldMain() 
     { 
      List<Hashtable> products = new List<Hashtable>(); 

      try 
      { 
       Hashtable product1 = new Hashtable(); 
       Hashtable product2 = new Hashtable(); 
       Hashtable product3 = new Hashtable(); 

       product1.Add("productName", "Empanada de Pollo"); 
       product1.Add("userName", "Fabio Roman"); 
       product1.Add("dateAndTime", "2016-08-11 15:50:52"); 
       product1.Add("domiciliosOrderId", "1932211-20160811155052"); 
       products.Add(product1); 

       product2.Add("productName", "Empanada de Carne"); 
       ... 
       products.Add(product2); 

       product3.Add("productName", "Empanada Mixta"); 
       ... 
       products.Add(product3); 

       Console.WriteLine("A message for debugging."); 
       Console.ReadLine(); 

       return products; 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("Exception details: " + e.ToString()); 
       Console.ReadLine(); 
       return products; 
      } 
     } 

     // More Methods and classes 
} 

现在作为WinForm的我有这个:

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Windows.Forms; 

namespace TheNameSpace 
{ 
    public partial class GuiForm : Form 
    { 
     public List<Hashtable> dataGridViewProducts; 

     public GuiForm() 
     { 
      InitializeComponent(); 
      InitializeBackgroundWorker(); 
      backgroundWorker.RunWorkerAsync(); // Initialize the whole process. 
     } 

     // Set up the BackgroundWorker object by 
     // attaching event handlers. 
     private void InitializeBackgroundWorker() 
     { 
      backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork); 
      backgroundWorker.RunWorkerCompleted += 
       new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerComplet); 
     } 


     private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 
     { 

     } 

     private void GuiForm_Load(object sender, EventArgs e) 
     { 
      int index = 0; 
      if (dataGridViewProducts != null && !dataGridViewProducts.Any()) 
      { 
       foreach (Hashtable product in dataGridViewProducts) 
       { 
        dataGridView1.ReadOnly = false; 
        dataGridView1.Rows.Add(); 
        dataGridView1.Rows[index].Cells[0].Value = product["productName"]; 
        dataGridView1.Rows[index].Cells[1].Value = product["userName"]; 
        dataGridView1.Rows[index].Cells[2].Value = product["dateAndTime"]; 
        dataGridView1.Rows[index].Cells[3].Value = product["domiciliosOrderId"]; 
        index++; 
       } 
       return; 
      } 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      // Logic for a delete-button 
     } 

     private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
     { 
      aldeloUpdater aldeloThread = new aldeloUpdater(); 
      this.dataGridViewProducts = aldeloThread.oldMain(); 

      //this.GuiForm_Load(); // ¿Do I need to make this call? ¿How to? 
      this.Show(); 
     } 

     private void backgroundWorker_RunWorkerComplet(object sender, RunWorkerCompletedEventArgs e) 
     { 
      if (e.Error != null) 
      { 
       MessageBox.Show(e.Error.Message); 
      } 
      else 
      { 
       MessageBox.Show(e.Result.ToString()); 
      } 
     } 
    } 
} 

我一直期待这样的结果:

enter image description here

但是,相反,我得到这个:

enter image description here

我知道我做错了什么,但我不知道那是什么,以及如何把它做好,我PHP后端开发,这是我的第一个C#程序。请帮忙。

回答

1

没有好的Minimal, Complete, and Verifiable code example,不可能知道什么是最好的解决方案。但是,根据您上面贴的代码,我可以提供一些建议:

  1. 虽然目前没有出现任何需要oldMain()是一个实例方法。您可以制作它public static List<Hashtable> oldMain(),然后将其称为aldeloUpdater.oldMain()。更好的是,为该方法创建一个单独的类,而不是将它放在本来是您的主要类的东西中。
  2. 您发表了评论阅读“我需要打这个电话吗?怎么办?。我会回答这个问题:“是的,你需要打这个电话。”由于该方法具有访问UI对象,特别是你的dataGridView1对象,你应该把它在RunWorkerCompleted事件处理程序:

    private void backgroundWorker_RunWorkerComplet(object sender, RunWorkerCompletedEventArgs e) 
    { 
        if (e.Error != null) 
        { 
         MessageBox.Show(e.Error.Message); 
        } 
        else 
        { 
         MessageBox.Show(e.Result.ToString()); 
         GuiForm_Load(sender, e); 
        } 
    } 
    

虽然,你不实际使用的sendere参数你GuiForm_Load()方法,所以在我看来,你可以忽略这些方法。

  1. 表单已通过Main()方法显示,方法是将其传递给Application.Run()方法。所以不应该有任何需要在DoWork事件处理程序中调用this.Show()。无论如何,这是错误的地方,因为你正在执行错误的线程。你应该删除那个电话。
+0

真棒@PeterDuniho感谢您的帮助,我做了所有你的建议,它是工作,虽然还有一点问题,'正在执行backgroundWorker_DoWork'两次,所以在DataGridView行被复制。是否有可能在'InitializeBackgroundWorker()'执行该方法?除了由构造函数中的'backgroundWorker.RunWorkerAsync()'触发的内容之外,我没有看到其他可以调用的地方。有关它的任何想法?再次感谢。 –

+0

您应该确保您只配置了一次“DoWork”事件处理程序。在构造函数中_Either_(通过调用'InitializeBackgroundWorker()'),或者在Visual Studio Designer中设置DoWork处理程序。如果没有一个好的[mcve],就不可能知道发生了什么事情,但通常当你得到这样的事情时,是因为你两次订阅了事件(每次订阅时你都会被调用一次)。 –

+0

哦,是的,就是这样。 –

0

我看到你的代码中的一些神秘的东西。

在用户界面上,您最好有一个很好的业务类来代表您的数据,而不是使用散列表的东西。然后你必须创建一个BindingList(你的类)并将其设置为你的datagridview的数据源。

那么你应该有你的“读取/处理”线程这将使在UI的一些调用的“业务对象”添加到的BindingList(DataGridView的将会被自动更新)。

如果读取/处理是一个死循环,也许你应该使用一个线程对象与循环,而不是其本身重启在RunWorkerCompleted事件一个BackgroundWorker。

当你看有一定的WinForms严重泄漏,你应该考虑尝试之前,麻烦多线程的概念去填补上一个按钮单击事件一个DataGridView。

点击事件可能是您的长时间抓取/处理,如果您的UI冻结2分钟,只要它正常工作就没有关系。

正如我所说:做到这一点。让它起作用。让它快速(和反应性)。

相关问题