我有一个列表视图,到目前为止工作正常。我遇到的问题是,有时需要几秒钟才能填充,因为我正在考虑添加1000多个项目。
所以我决定使用BackgroundWorker填充ListView,但我遇到的问题是我无法使用BackgroundWorker线程上的UI线程中的控件。
为了解决这个问题,我编写了下面你看到的代码。我知道返回的ListView中有很多项,但是当我在表单中将它分配给我的ListView组件时,没有显示任何内容,我不知道为什么。
在我开始拍打自己之前请帮助我:)
public ListView listImages(string path, BackgroundWorker worker)
{
ListView lv = new ListView();
lv.Items.Clear();
int count = 0;
int total = 0;
string[] extensions = new string[] { ".jpg", ".JPG", ".png", ".PNG", ".bmp", ".BMP" };
lv.Columns.Add("Filename", 300);
lv.Columns.Add("Date taken", 150);
lv.Columns.Add("Size", 150);
DirectoryInfo dir = new DirectoryInfo(path);
IEnumerable<FileInfo> files = dir.EnumerateFiles("*.*", SearchOption.AllDirectories).Where(f => extensions.Contains(f.Extension));
total = files.Count();
foreach (FileInfo f in files)
{
DateTime dt = File.GetCreationTime(Path.Combine(f.Directory.ToString(), f.Name));
string fsize = FormatBytes(f.Length);
count++;
ListViewItem lSingleItem = lv.Items.Add(f.Name);
lSingleItem.SubItems.Add(dt.ToString("dd MMMM yyyy"));
lSingleItem.SubItems.Add(fsize);
lSingleItem.Tag = Path.Combine(f.Directory.ToString(), f.Name);
worker.ReportProgress((count * 100) / total);
}
return lv;
}
private void buttonLeftBrowse_Click(object sender, EventArgs e)
{
if (_bwListImages.IsBusy != true)
{
pgf = new ProgressBarForm();
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
string path = folderBrowserDialog.SelectedPath;
this.textBoxLeftFolder.Text = path;
object[] parameters = new object[] { path };
_bwListImages.RunWorkerAsync(parameters);
pgf.ShowDialog();
}
}
}
private void _bwListImages_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
object[] parameters = e.Argument as object[];
resetViewsColor();
disableButtons();
e.Result = core.listImages((string)parameters[0], worker);
checkButtons();
}
private void _bwListImages_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pgf.progressBar.Value = e.ProgressPercentage;
}
private void _bwListImages_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
listViewLeft = (ListView)e.Result;
pgf.Close();
}
谢谢 Crouz
答案 0 :(得分:1)
我怀疑问题可能是您在后台线程中创建ListView
,使其成为ListView
的有效UI线程。
也许使用后台线程只返回项目列表,并将它们分配给UI线程中的ListView
。
您的后台工作者工作方法应该返回List<string>
个文件名,并且在后台工作完成事件中,您应该使用ListView.Items.Addrange
将文件名添加到ListView
答案 1 :(得分:0)
什么是listViewLeft
?我猜是ListView
?如果是listViewLeft.ItemsSource
,则应指定wpf
;如果是listViewLeft.DataSource
,则应指定winform
,而不是ListView
答案 2 :(得分:0)
正如Rotem指出的那样,你可以通过在工作线程(Say AssignListview)中引发事件来做到这一点,然后你可以通过以下方式将调用委托给实际的赋值 this.BeginInvoke((MethodInvoker)委托{ActualAssignmentFunction();});
ActualAssignmentFunction();在UI线程中执行。