人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

VB2008.NETのListViewにおけるItemSelectionChangedイベントで質問です。

ShiftキーやCtrl+Aで複数のitemをまとめて選択した場合、
まとめて選択される過程の一つ一つでItemSelectionChangedイベントが発生しています。
現在発生しているItemSelectionChangedイベントが、この過程のうち
「最後の一つかどうかを認識する方法」をご存知の方、アドバイスをいただければ幸いです。

といいますのは、選択内容にあわせたHTMLファイル書き出しを行う処理をしているのですが
出力させたいのは「選択された内容にあわせて」であって「選択過程の内容にあわせて」では
ないにもかかわらず、この方法がわからないので処理が重くなって悩んでいるからです。

よろしくお願いいたします。

●質問者: くじぇ
●カテゴリ:コンピュータ
✍キーワード:.NET HTML VB2008 いるか アドバイス
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● HALSPECIAL
●18ポイント

ListView.SelectedIndexChanged イベント


上記リンクのVBサンプル中のSelectedIndexChangedイベントの記述にある通り、選択された複数行をコレクションとして取得可能な様です。

Private Sub ListView1_SelectedIndexChanged_UsingItems _
 (ByVal sender As Object, ByVal e As System.EventArgs) _
 Handles ListView1.SelectedIndexChanged

 Dim breakfast As ListView.SelectedListViewItemCollection = _
 Me.ListView1.SelectedItems
 Dim item As ListViewItem
 Dim price As Double = 0.0
 For Each item In breakfast
 price += Double.Parse(item.SubItems(1).Text)
 Next

  ' Output the price to TextBox1.
 TextBox1.Text = CType(price, String)
End Sub



内容は確かではありませんが、こんな感じでしょうか。

順番が期待通りでなければ、SORTの処理を入れることになります。

Private Sub ListView1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListView1.SelectedIndexChanged

 Dim myitems As ListView.SelectedListViewItemCollection = Me.ListView1.SelectedItems
 If myitems.Count = 0 Then Exit Sub

 Dim strMakerComment() As String = New String(myitems.Count) {}
 Dim i As Integer

 i = 0
 For Each datItem As ListViewItem In myitems
 strMakerComment(i) = "X = " & datItem.SubItems(enmListView1.X).Text & " Y = " & datItem.SubItems(enmListView1.X).Text & vbCrLf
 i += 1
 Next
 Array.Resize(strMakerComment, i + 1)

 If strMakerComment.Length > 0 Then
 vidFileReflesh(strMakerComment) ' ここでファイル書き出し
 End If

End Sub

◎質問者からの返答

HALSPECIALさん、毎度ありがとうございます。

ご提案して頂いたコードでは、ListView1の中身を10件選択した場合、私がコメントで提示したプログラムと同様に

vidFileReflesh(strMakerComment)が10回呼び出されないでしょうか?

私は「選択された内容にあわせて」vidFileReflesh(strMakerComment)が1回のみ書き出し処理を

行うようにできれば、今回の件は大幅にスピードアップするのではないかと考えています。

しかし、その方法が今のところわからないので質問しています。

質問文がわかりづらくてお手数をお掛けしていますが、よろしくお願いいたします。


2 ● khazad-Lefty
●52ポイント ベストアンサー

まず、

ListView.SelectedIndices プロパティ (System.Windows.Forms)

から考えると、このイベントで「最後の一つかどうか」を判断することはできないと考えられます。

(そのような情報を判断するフラグなどの記述がない)

>選択内容にあわせたHTMLファイル書き出しを行う処理をしているのですが

これって、選択内容が変更されるたびにその都度書き出しを行う必要があるのでしょうか?

「最後の一つかどうか」を認識できたとしても、

たとえば、Ctrlキーで複数選択した場合や、Shift+下矢印などで、は、

結局行をクリックして選択範囲を増やす度に書き出しが行われるわけで、

選択途中の意図しないHTML出力が行われるのは避けられないのですが、

それは問題ないのでしょうか?

素直に考えると、選択とは別に「HTML書き出し」のボタンを用意して、

その時に、ListView.SelectedIndices を参照して、選択列を取得するのが自然じゃないかと思うのですが。

(スペックにもよりますが、その方が使用者のストレスは少なくなる気もします)

「最後の一つかどうか」を判断できないというのは、それが必要な状況が考えにくいからということでもあると思います。


で、どうしても書出しボタンは用意できないというのであれば、

たとえば「最後の選択変更から0.2秒後に書出し処理を行う」という形で、

Timerコントロール(System.Windows.Timer)を利用する方法が考えられます。

Timer クラス (System.Windows.Forms)

マルチスレッドとか考えなくても良さそうだし。

Private Sub ListView1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListView1.SelectedIndexChanged
 timer1.stop()
 timer1.Interval=200  '<-この行はなくてもいいかも
 timer1.start()
End Sub

private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1_Tick
timer1.stop()
'(やりたい処理)
end sub

これなら選択する度にタイマーにリセットがかかるので、

処理は軽くなるんじゃないかと思います。

◎質問者からの返答

khazad-Leftyさん、コメントでタイマーを指摘してくださったtakntさんありがとうございます。

教えて頂いた方法でかなり高速化になりました。ありがとうございます。

ファイルの書き換え処理は、webbrowserコンポーネントで表示する画面の書き換えで使いたかったのですが

自分で書き換え部分をbackgroundコンポーネントでスレッド化したときに、webbrowserコンポーネントに関連する

例外が多発して挫折した経験がありました。

その為Timerクラスを折角提示していただいても、てっきり形を変えたスレッド処理だと

思いこんでいたのですが、食わず嫌いはいけないですねorz

本当にありがとうございました!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ