【C#】ListViewまたはTreeViewの描画を一時停止して処理を高速化する

C#

ListViewまたはTreeViewコントロールに大量のデータを登録する場合、その描画処理は非常に時間がかかることがあります。この問題を解決するために、ListViewまたはTreeViewの描画を一時的に停止し、追加処理終了後に描画を再開する方法を紹介します。

準備

フォーム上にリストビューを配置。名前はlistView1。
ボタンを二つ配置。button1, button2

サンプルコード

10,000件のデータを登録する場合に、どれだけ時間が掛かるかを比較します。
button1:対策なしの場合
button2:描画停止をした場合

using System;
using System.Collections;
using System.Windows.Forms;
using System.Diagnostics; // Stopwatch

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // リストビュー初期化
            InitializeListView();
        }
        // リストビュー初期化
        private void InitializeListView()
        {
            // リストビューのプロパティ設定
            listView1.View = View.Details;
            listView1.FullRowSelect = true;

            // カラムヘッダの初期化
            listView1.Columns.Add("Name", -2, HorizontalAlignment.Left);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch(); // Stopwatchインスタンスを作成
            stopwatch.Start(); // 時間計測を開始

            // 例として、10,000個の項目を追加
            for (int i = 0; i < 10000; i++)
            {
                listView1.Items.Add("Item " + i.ToString());
            }

            // 計測した時間をメッセージボックスで表示
            stopwatch.Stop(); // 時間計測を終了
            MessageBox.Show($"ListViewの描画にかかった時間: {stopwatch.Elapsed.TotalSeconds.ToString("F1")} 秒");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Stopwatch stopwatch = new Stopwatch(); // Stopwatchインスタンスを作成
            stopwatch.Start(); // 時間計測を開始

            // ListViewの描画を停止  ★
            listView1.BeginUpdate();

            // 例として、10,000個の項目を追加
            for (int i = 0; i < 10000; i++)
            {
                listView1.Items.Add("Item " + i.ToString());
            }

            // ListViewの描画を再開  ★
            listView1.EndUpdate();

            // 計測した時間をメッセージボックスで表示
            stopwatch.Stop(); // 時間計測を終了
            MessageBox.Show($"ListViewの描画にかかった時間: {stopwatch.Elapsed.TotalSeconds.ToString("F1")} 秒");
        }
    }
}

実行結果

描画停止の対策なしの場合は4.7秒。

描画停止の対策ありの場合は0.3秒。劇的に速くなりました。

まとめ

ListViewまたはTreeViewコントロールに大量のデータを登録する場合、BeginUpdate() と EndUpdate() を適切に使い、処理時間を短縮しましょう。

タイトルとURLをコピーしました