0

我有一个到目前为止运行良好的列表视图。我遇到的问题是,当我正在考虑添加 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();
}

谢谢克鲁兹

4

3 回答 3

1

我怀疑问题可能是您正在ListView后台线程中创建ListView.

也许使用后台线程只返回项目列表,并将它们分配给ListViewUI 线程。

您的后台工作者工作方法应该返回一个List<string>文件名,并且在后台工作者完成事件中,您应该使用ListView.Items.Addrange将文件名添加到ListView

于 2012-11-28T15:07:04.187 回答
0

什么是listViewLeft?我猜是ListView吗?listViewLeft.ItemsSource您应该在wpflistViewLeft.DataSource在 的情况下分配winform,但不是ListView

于 2012-11-28T15:07:23.683 回答
0

正如Rotem指出的那样,您可以通过在工作线程中引发事件(例如AssignListview)来做到这一点,然后您可以通过以下方式将调用委托给实际分配 this.BeginInvoke((MethodInvoker)delegate { ActualAssignmentFunction(); }) ;

实际分配函数();在 UI 线程中执行。

于 2013-01-11T06:27:51.570 回答