如何动态更新列表框
本文关键字:更新 列表 动态 何动态 | 更新日期: 2024-10-22 01:43:42
我正在制作一个搜索实用程序并使用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"中。我无法理解在 else 条件下放置什么,以便更新ListBox
.
我要做的是在弹出窗体上公开一些属性,以便您可以判断它是否处于打开状态并可以访问列表框。
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;
}
}
然后在调用窗体上,我将订阅 ProcessingChanged 事件,并使用您通过 ProcessingChangedEventArgs 传递的数据更新列表框。这是调用窗体的代码
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();
}
}
}
你不应该在ProgressChanged
事件处理程序中工作
- 您将无法访问结果,因为它只传递了一个用于进度和用户状态的 int
- 这是在 UI 线程上。 重点是在后台线程上进行处理
- 事件处理程序的名称
DoWork
很清楚,这是您应该进行处理的位置。
回答你的问题。 由于在事件处理程序中创建 ListBox,因此它超出了 if
语句的范围。 您需要在更全局的范围内创建它。 然后添加到它ResultListBox.Items.Add("ResultListBox" + i.ToString());