2012-11-28 21 views
0

我有一個到目前爲止工作得很好的listview。我遇到的問題是,有時需要幾秒鐘才能填充,因爲我正在尋找添加許多1000個項目。不能從背景工作者分配返回的ListView

所以我決定用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

winform或wpf? –

回答

1

我懷疑問題可能是您在後臺線程創建ListView,使該有效UI線程爲ListView

也許使用後臺線程只返回項目列表,並將它們分配給UI線程中的ListView

你BackgroundWorker的工作方法應返回的文件名的List<string>,並在BackgroundWorker的完成情況,你應該使用ListView.Items.Addrange的文件名添加到ListView

+0

你是怎麼做的?謝謝 – Crouzilles

+0

已更新的答案。 – Rotem

+0

謝謝,現在這個工作。 – Crouzilles

0

是什麼listViewLeft?我想這是ListView?你應該在wpflistViewLeft.DataSource情況的winform情況下分配listViewLeft.ItemsSource,但不ListView

0

由於Rotem公司指出,你可以做,通過提高工作線程(說AssignListview)的事件,那麼你可以做委託通話通過以下方式實際分配 this.BeginInvoke((MethodInvoker)delegate {ActualAssignmentFunction();});

ActualAssignmentFunction();在UI線程中執行。