2013-12-18 57 views
0

我在製作搜索實用程序並使用BackgroundWorker進行搜索。我希望一旦找到第一個結果,就會打開一個新窗口,並顯示第一個元素ListBox。現在,我希望一旦找到後續結果,應該用這些結果更新ListBox
我認爲的方法是在找到結果後立即報告進度,並將「新」和「更新」作爲userState傳遞給方法。
根據userState,我可以決定是創建新的Form還是更新現有的。
下面是代碼: -如何動態更新列表框?

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     if (e.UserState.ToString() == "New") 
     { 
      Form ResultForm = new Form(); 
      ResultForm.Name = "ResultForm" + i.ToString(); 
      LastFormName = ResultForm.Name; 
      ListBox ResultListBox = new ListBox(); 
      ResultListBox.DataSource = SearchList; 
      ResultListBox.Name = "ResultListBox" + i.ToString(); 
      LastListName = ResultListBox.Name ; 
      ResultForm.Container.Add(ResultListBox); 
      ResultListBox.Show(); 
      ResultForm.Show(); 
      i++; 
     } 
     else 
     { 
      ; 
     } 
    } 

我已經存儲了最後打開的窗體的名稱和它在列表框變量和LastFormName「LastListName」。 我無法理解要在其他條件中放置什麼,以便更新ListBox

回答

2

我會做的是公開彈出窗體上的一些屬性,以便您可以知道它是否打開並有權訪問列表框。

public partial class Popup : Form 
    { 
    public bool isOpen; 
    public ListBox PopupListBox; 

    public Popup() 
    { 
     InitializeComponent(); 
    } 

    void Popup_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     isOpen = false; 
    } 

    private void Popup_Load(object sender, EventArgs e) 
    { 
     this.FormClosing += Popup_FormClosing; 
     PopupListBox = popupListBox; 
    } 
} 

然後調用窗體上我會訂閱ProcessedChanged事件和更新與您正在通過ProcessedChangedEventArgs數據列表框。這裏是呼叫形式的代碼

public partial class Form1 : Form 
{ 
    Popup popupForm = new Popup(); 
    BackgroundWorker backgroundWorker = new BackgroundWorker(); 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     backgroundWorker.WorkerSupportsCancellation = true; 
     backgroundWorker.WorkerReportsProgress = true; 
     backgroundWorker.DoWork += backgroundWorkerDoWork; 
     backgroundWorker.ProgressChanged += backgroundWorkerProgressChanged; 
     backgroundWorker.RunWorkerCompleted += backgroundWorkerRunWorkerCompleted; 
    } 

    void backgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     if ((e.Cancelled == true)) 
     { 
      //What do you want to do if Cancelled? 
     } 

     else if (!(e.Error == null)) 
     { 
      //What do you want to do if there is an error? 
     } 
     else 
     { 
      //What do you want to do when it is done? 
     } 
    } 

    void backgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     if (!popupForm.isOpen || popupForm == null) 
     { 
      popupForm = new Popup(); 
      popupForm.Show(); 
      popupForm.isOpen = true; 
     } 
     else 
     { 
      popupForm.Activate(); 
      popupForm.WindowState = FormWindowState.Normal; 
     } 

     popupForm.PopupListBox.Items.Add(e.ProgressPercentage.ToString() + "%"); 
    } 

    void backgroundWorkerDoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker worker = sender as BackgroundWorker; 

     for (int i = 1; (i <= 10); i++) 
     { 
      if ((worker.CancellationPending == true)) 
      { 
       e.Cancel = true; 
       break; 
      } 
      else 
      { 
       // Perform a time consuming operation and report progress. 
       System.Threading.Thread.Sleep(500); 
       worker.ReportProgress((i * 10)); 
      } 
     } 
    } 

    private void buttonStart_Click(object sender, EventArgs e) 
    { 
     if (backgroundWorker.IsBusy != true) 
     { 
      backgroundWorker.RunWorkerAsync(); 
     } 
    } 

    private void buttonCancel_Click(object sender, EventArgs e) 
    { 
     if (backgroundWorker.WorkerSupportsCancellation == true) 
     { 
      backgroundWorker.CancelAsync(); 
     } 
    } 
} 
+0

+1非常感謝! –

0

你不應該在ProgressChanged事件處理

  1. 做的工作,您將無法訪問的結果,因爲它是唯一通過一個int進步和用戶狀態
  2. 這是在UI線程。整個要點是在後臺線程上處理你的數據。
  3. 事件處理程序的名稱爲DoWork明確表示這是你應該處理的地方。

在回答你的問題。由於您在事件處理程序中創建了列表框,因此它會超出if語句的範圍。您需要在更全局的範圍內創建它。然後添加到它ResultListBox.Items.Add("ResultListBox" + i.ToString());