0

これまでのところうまく機能しているリストビューがあります。私が遭遇した問題は、何千ものアイテムを追加することを検討していたため、入力に数秒かかることがあるということでした。

そこで、ListViewにBackgroundWorkerを追加することにしましたが、発生した問題は、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

4

3 に答える 3

1

ListView問題は、バックグラウンドスレッドで作成しているため、の効果的なUIスレッドになっている可能性があると思われますListView

おそらく、バックグラウンドスレッドを使用してアイテムのリストのみを返し、それらをListViewUIスレッドのに割り当てます。

backgroundworkerの作業メソッドはList<string>ファイル名のaを返す必要があり、backgroundworkerの完了イベントではListView.Items.Addrange、ファイル名をに追加するために使用する必要があります。ListView

于 2012-11-28T15:07:04.187 に答える
0

listViewLeftですか?私はそれだと思いListViewますか?の場合またはのlistViewLeft.ItemsSource場合に割り当てる必要がありますが、wpflistViewLeft.DataSourcewinformListView

于 2012-11-28T15:07:23.683 に答える
0

Rotemが指摘したように、ワーカースレッドでイベントを発生させることでこれを行うことができ(Say AssignListview)、次の方法で実際の割り当てに呼び出しを委任できます。BeginInvoke((MethodInvoker)delegate {ActualAssignmentFunction();}) ;

ActualAssignmentFunction(); UIスレッドで実行されます。

于 2013-01-11T06:27:51.570 に答える