teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

追記

2021/12/31 02:41

投稿

vann_2921
vann_2921

スコア190

answer CHANGED
@@ -55,4 +55,23 @@
55
55
  ListView1.Items.AddRange(ListViewItems.ToArray())
56
56
  End Sub
57
57
  End Class
58
+ ```
59
+
60
+ ### 追記2
61
+ 画像の生成が遅いときは必要になってから画像を生成する方法にすると立ち上がりが早くなるかもしれません。サンプルでは早くなりましたが元の画像が重いと効果があるかは分かりません。
62
+ ```VB
63
+ Dim i As Integer = 0 '生成した画像の数
64
+ Private Sub ListView1_RetrieveVirtualItem(sender As Object, e As RetrieveVirtualItemEventArgs) Handles ListView1.RetrieveVirtualItem
65
+ 'パスから画像を読み込む場合は事前にファイルのパスのリストを保存しておく
66
+ If e.ItemIndex < 10000 AndAlso e.Item Is Nothing Then
67
+ 'i番目の画像を生成する
68
+ Dim thumbnail As New Bitmap(120, 120)
69
+ Using Graphics1 As Graphics = Graphics.FromImage(thumbnail)
70
+ Graphics1.FillRectangle(New SolidBrush(Color.FromArgb(i / 1000 * 25, 0, 0)), New Rectangle(0, 0, 120, 120))
71
+ End Using
72
+ ImageList1.Images.Add(thumbnail)
73
+ e.Item = New ListViewItem(e.ItemIndex.ToString(), e.ItemIndex)
74
+ i += 1
75
+ End If
76
+ End Sub
58
77
  ```

1

追記

2021/12/31 02:41

投稿

vann_2921
vann_2921

スコア190

answer CHANGED
@@ -1,6 +1,7 @@
1
1
  ListViewには仮想モードいう表示範囲しか描画しないようにして処理の軽減が可能なそうです。
2
2
  検索のキーワードとしては「.net listview 描画 遅い」で検索するとKOZ6.0さんが質問への追記・修正の依頼にて提示された記事が出てきます。
3
3
  試しに使ってみたコードです。[参考にしたサイト](https://www.ipentec.com/document/csharp-listview-using-virtual-listview)
4
+ 効果としては120*120のビットマップをListViewに10000件追加する処理で、VirtualModeを使わない場合は3分ちょっとかかっていたのが5秒程度になりました。
4
5
 
5
6
  ```VB
6
7
  Public Class Form1
@@ -28,4 +29,30 @@
28
29
  End Class
29
30
  ```
30
31
  注意事項としてはVirtualModeがTrueのときはListViewのItemsプロパティでのアイテムの追加ができなくなります。
31
- 例ではRetrieveVirtualItemイベントのRetrieveVirtualItemEventArgsを介して、アイテムが未設定であれば新しくアイテムを設定しています。
32
+ 例ではRetrieveVirtualItemイベントのRetrieveVirtualItemEventArgsを介して、アイテムが未設定であれば新しくアイテムを設定しています。
33
+
34
+ ### 追記
35
+ 比較用のVirtualModeを使わないコード
36
+ ```VB
37
+ Public Class Form1
38
+ Private Images As New List(Of Bitmap)
39
+ Private ListViewItems As New List(Of ListViewItem)
40
+ Public Sub New()
41
+
42
+ ' この呼び出しはデザイナーで必要です。
43
+ InitializeComponent()
44
+
45
+ ' InitializeComponent() 呼び出しの後で初期化を追加します。
46
+ For i As Integer = 0 To 9999
47
+ Dim thumbnail As New Bitmap(120, 120)
48
+ Using Graphics1 As Graphics = Graphics.FromImage(thumbnail)
49
+ Graphics1.FillRectangle(New SolidBrush(Color.FromArgb(i / 1000 * 25, 0, 0)), New Rectangle(0, 0, 120, 120))
50
+ End Using
51
+ Images.Add(thumbnail)
52
+ ListViewItems.Add(New ListViewItem(i.ToString(), i))
53
+ Next
54
+ ImageList1.Images.AddRange(Images.ToArray())
55
+ ListView1.Items.AddRange(ListViewItems.ToArray())
56
+ End Sub
57
+ End Class
58
+ ```