2013-12-18 58 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());