2010年5月17日月曜日

ListBox : 項目が存在しないエリアを選択しても選択されないように

なんで.Netのコントロールは、細かい動作に不具合が多いのだろう

ListBox(CheckedListBox)のコントロールの動きについて、項目がListBoxの高さ一杯まで埋まっていない場合、項目がないエリアをクリックすると、選択された動作(SelectedIndexChangedイベント発生)し、違和感がある。
VB6のコントロールでは、こんな動作しなかったのに....
おかげで、ListBoxを利用した抽出画面にお客さんからクレーム来たよ(泣)

VB6と同様に項目が存在しないエリアを選択しても選択されないようにするには...

ListBoxコントロールにはクリックした場所からその項目のIndexを取得するメソッド(IndexFromPoint)があります。
これを利用し、継承コントロールを作りました。


Public Class CustomListBox
    Inherits ListBox


    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Dim _blnHandled As Boolean = False


        Select Case m.Msg
            Case &H201, &H202, &H203                                             'WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDBL
                Dim _ptMouse As Point = MyBase.PointToClient(MousePosition)
                Dim _index As Integer = MyBase.IndexFromPoint(_ptMouse)
                If _index < 0 Then
                    _blnHandled = True
                ElseIf _index < Items.Count Then
                    '                                                               クリックした位置がリストボックスコンテンツのある範囲か無い範囲かの計算    
                    Dim _lngContentsHeight As Integer = 0
                    Dim _indexSizeCalc As Integer = MyBase.IndexFromPoint(0, 0)      '先頭位置のインデックス


                    Do While (_indexSizeCalc < Items.Count) And (_lngContentsHeight <= Height)
                        _lngContentsHeight += GetItemHeight(_indexSizeCalc)                         'コンテンツ高さ計算
                        _indexSizeCalc += 1
                    Loop
                    If (_ptMouse.Y > _lngContentsHeight) Then                       '?領域外
                        _blnHandled = True
                    End If
                End If
        End Select


        If (Not _blnHandled) Then                                                   '?処理する
            MyBase.WndProc(m)
        End If
    End Sub
End Class

0 件のコメント:

コメントを投稿