Emotion Wave Tech Blog

福岡にあるエモーションウェーブ株式会社のエンジニアが書いています。

ListBoxの項目をD&Dで並び替え

.netのListBoxの項目の並び替えをD&D(ドラッグアンドドロップ)で並び替えたいと思い、とりあえずマウスポインタの座標にあるアイテムの取得方法を検索していたらListBoxのメソッドにIndexFromPointという素敵なメソッドがあったので、VB.netで実装してみた。 コードは↓な感じ。 開発環境は、Win7でvs2005。

本当は、Index番号で削除してあげるのがいいけど、今回は、ListBoxのアイテムは、ユニークだったので、項目名で削除してる。(手抜k(ry 継承コントロールとかで実装すると割と便利かも。

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'リストボックスに項目の追加
        Me.ListBox1.Items.AddRange(New String() {"ミカン", "リンゴ", "スイカ", "バナナ"})

        'D&Dを許可
        Me.ListBox1.AllowDrop = True

    End Sub

    Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown

        'マウスの左クリック以外は、処理しない
        If Not e.Button = Windows.Forms.MouseButtons.Left Then Return

        'マウスポインタのある位置のアイテムを取得する
        Dim index As Integer = Me.ListBox1.IndexFromPoint(e.Location)

        '現在位置が取得出来ない場合は、処理しない
        If index = -1 Then Return

        'ドラッグ&ドロップ処理を開始する
        Me.ListBox1.DoDragDrop(Me.ListBox1.Items(index), DragDropEffects.All)
    End Sub


    Private Sub ListBox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter

        'String型の場合は、エフェクトをMoveに変更
        If e.Data.GetDataPresent(GetType(String)) Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop
        'ドロップされたデータがStrng型ではない時は処理しない
        If Not e.Data.GetDataPresent(GetType(String)) Then Return

        Dim item As String = CStr(e.Data.GetData(GetType(String)))
        'ドロップされたデータを削除する。
        Me.ListBox1.Items.Remove(item)

        '画面座標からクライアント座標に変換し、カーソル位置のインデックスを取得
        Dim Addindex As Integer = _
                Me.ListBox1.IndexFromPoint(Me.ListBox1.PointToClient(New Point(e.X, e.Y)))

        '取得出来なかった場合は、一番最後を追加位置に設定(最終index+1)
        If Addindex = -1 Then Addindex = Me.ListBox1.Items.Count

        '追加位置にドロップされたデータを追加する。
        Me.ListBox1.Items.Insert(Addindex, item)
        '選択を解除
        Me.ListBox1.SelectedItem = Nothing
        'ドロップしたデータを選択
        Me.ListBox1.SelectedItem = item

    End Sub

End Class