ラベル VB の投稿を表示しています。 すべての投稿を表示
ラベル VB の投稿を表示しています。 すべての投稿を表示

2013年2月26日火曜日

[VB.NET]DataGridViewでのドラッグアンドドロップ

以下のサイトにあったC#のソースコードをVB.NETに修正&一部変更しました。
http://social.msdn.microsoft.com/forums/ja-JP/csharpgeneralja/thread/e59a4043-6298-4653-809f-5c8fcf04f2e6

変更点として、
行セレクトモード⇒セルセレクトモードにして、
特定のカラム(ここではColumn0のImage)上でしかドラッグアンドドロップが起動しないようにしています。




Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load


        'テストの準備
        'データグリッド
        Dim objTable As New DataTable
        Dim objDR As DataRow
        objTable.Columns.Add(New DataColumn("項目1", GetType(String)))
        objTable.Columns.Add(New DataColumn("項目2", GetType(Integer)))
        For i As Integer = 0 To 10
            objDR = objTable.NewRow
            objDR("項目1") = i.ToString & i.ToString & i.ToString & i.ToString
            objDR("項目2") = i
            objTable.Rows.Add(objDR)
        Next
        Me.DataGridViewUe.DataSource = objTable


        For Each col As DataGridViewColumn In Me.DataGridViewUe.Columns
            col.SortMode = DataGridViewColumnSortMode.NotSortable
        Next
        Me.DataGridViewUe.AllowDrop = True

    End Sub

Private Sub DataGridViewUe_MouseDown(sender As System.Object, e As MouseEventArgs) Handles DataGridViewUe.MouseDown

        OwnBeginGrabRowIndex = -1

        If (e.Button <> MouseButtons.Left And MouseButtons.Left <> MouseButtons.Left) Then Return


        Dim hit As DataGridView.HitTestInfo = DataGridViewUe.HitTest(e.X, e.Y)

    If hit.ColumnIndex <> 0 Then Return
        If (hit.Type <> DataGridViewHitTestType.Cell) Then Return


        'ドラッグ&ドロップの開始
        'クリック時などは -1 に戻らないが問題なし
        OwnBeginGrabRowIndex = hit.RowIndex


        'Me.TextBox1.Text = OwnBeginGrabRowIndex
        'Me.TextBox2.Text = "すたーと"
        DataGridViewUe.DoDragDrop(OwnBeginGrabRowIndex, DragDropEffects.Move)



    End Sub
  
 
    Private Sub DataGridViewUe_DragOver(sender As System.Object, e As DragEventArgs) Handles DataGridViewUe.DragOver


        'Integer型の場合は、エフェクトをMoveに変更(ここはカラムによるのかな?)
        If e.Data.GetDataPresent(GetType(Integer)) Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If

        Me.DataGridViewUe.Rows(OwnBeginGrabRowIndex).Selected = True


        Dim kara, made As Integer
        Dim tugi As Boolean
        Dim valid As Boolean = DecideDropDestinationRowIndex(DataGridViewUe, e, kara, made, tugi)


        'ドロップ先マーカーの表示・非表示の制御
        Dim needRedraw As Boolean = (valid <> DropDestinationIsValid)
        If (valid) Then
            needRedraw = (needRedraw Or (made <> DropDestinationRowIndex) Or (tugi <> DropDestinationIsNextRow))
        End If

        If (needRedraw) Then
            If (DropDestinationIsValid) Then
                DataGridViewUe.InvalidateRow(DropDestinationRowIndex)
            End If
            If (valid) Then
                DataGridViewUe.InvalidateRow(made)
            End If
        End If

        DropDestinationIsValid = valid
        DropDestinationRowIndex = made
        DropDestinationIsNextRow = tugi

    End Sub

    Private Sub DataGridViewUe_DragLeave(sender As System.Object, e As DragEventArgs) Handles DataGridViewUe.DragLeave
        If (DropDestinationIsValid) Then
            DropDestinationIsValid = False
            DataGridViewUe.InvalidateRow(DropDestinationRowIndex)
        End If
    End Sub

    Private Sub DataGridViewUe_DragDrop(sender As System.Object, e As DragEventArgs) Handles DataGridViewUe.DragDrop

        Dim kara, made As Integer
        Dim tugi As Boolean

        If (DecideDropDestinationRowIndex(DataGridViewUe, e, kara, made, tugi) = False) Then
            Return
        End If

        DropDestinationIsValid = False

        'データの移動
        made = MoveDataValue(kara, made, tugi)

        Me.DataGridViewUe.CurrentCell = Me.DataGridViewUe(Me.DataGridViewUe.CurrentCell.ColumnIndex, made)


        Me.DataGridViewUe.Invalidate()


    End Sub


    Private Sub DataGridViewUe_RowPostPaint(sender As System.Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridViewUe.RowPostPaint

        'ドロップ先のマーカーを描画
        If (DropDestinationIsValid And e.RowIndex = DropDestinationRowIndex) Then
            Using objpen As New Pen(Color.Red, 4)
                Dim y As Integer = IIf(DropDestinationIsNextRow = False, e.RowBounds.Y + 2, e.RowBounds.Bottom - 2)
                e.Graphics.DrawLine(objpen, e.RowBounds.X, y, e.RowBounds.X + 50, y)
            End Using
        End If
    End Sub



    'ドロップ先の行の決定
    Private Function DecideDropDestinationRowIndex(grid As DataGridView, e As DragEventArgs, ByRef kara As Integer, ByRef made As Integer, ByRef tugi As Boolean) As Boolean


        'If Not e.Data.GetDataPresent(GetType(Integer)) Then Return
        kara = DirectCast(e.Data.GetData(GetType(Integer)), Integer)

        '元の行が追加用の行であれば、常に false
        If (grid.NewRowIndex <> -1 And grid.NewRowIndex = kara) Then
            made = 0
            tugi = False
            Return False
        End If



        Dim clientPoint As Point = grid.PointToClient(New Point(e.X, e.Y))
        '上下のみに着目するため、横方向は無視する
        clientPoint.X = 1
        Dim hit As DataGridView.HitTestInfo = grid.HitTest(clientPoint.X, clientPoint.Y)

        made = hit.RowIndex
        If (made = -1) Then

            Dim top As Integer = IIf(grid.ColumnHeadersVisible, grid.ColumnHeadersHeight, 0)
            top += 1  '// ...

            If (top > clientPoint.Y) Then
                'ヘッダへのドロップ時は表示中の先頭行とする
                made = grid.FirstDisplayedCell.RowIndex
            Else
                '最終行へ
                made = grid.Rows.Count - 1
            End If

        End If

        '追加用の行は無視
        If (made = grid.NewRowIndex) Then
            made -= made
        End If

        'Me.NumericTextBox1.Text = made

        tugi = (made > kara)
        Return (kara <> made)

    End Function



    'データの移動
    Private Function MoveDataValue(ByVal kara As Integer, ByVal made As Integer, ByVal tugi As Boolean) As Integer

        Dim table As DataTable = DirectCast(DataGridViewUe.DataSource, DataTable)

        '移動するデータの退避(計算列があればたぶんダメ)
        Dim rowData = table.Rows(kara).ItemArray
        Dim row As DataRow = table.NewRow()
        row.ItemArray = rowData

        '移動元から削除
        table.Rows.RemoveAt(kara)
        If (made > kara) Then made = made - 1
        '移動先へ追加
        If (tugi) Then made = made + 1

        If (made <= table.Rows.Count) Then
            table.Rows.InsertAt(row, made)
        Else
            table.Rows.Add(row)
        End If

        Return table.Rows.IndexOf(row)
    End Function



End Class





2012年6月15日金曜日

[VB.NET]テキストボックスにて条件に合わない入力の場合はキャンセル

From Evernote:

[VB.NET]テキストボックスにて条件に合わない入力の場合はキャンセル

  
Private Sub txtEigen_KeyPress( ByVal sender As System.Object,  _
   ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtEigen.KeyPress
    
    '例:Aの入力をなかったことにする
     If e.KeyChar = "A" Then
         e.Handled = True
    End If

End Sub

[.NET]列挙型(Enum)のオリジナル使い方

From Evernote:

[.NET]列挙型(Enum)のオリジナル使い方

フツウに宣言して自分変数として使うけど、
その他色々使うメモ。

'宣言部==============================
Private Enum ABCD As Integer
        A = 1
        B = 2
        C = 3
        D = 4
End Enum

'①通常の使い方
If tmp = ABCD.A.GetHashCode
     MessageBox.Show("あたり")
End If
'②定義されている数や中身を知りたい場合
Dim cnt As Integer = 0 
For Each EnumNumber As ABCD In System.Enum.GetValues(GetType (ABCD))
     cnt += 1
     MessageBox.Show(EnumNumber)
Next


'ここからは自分流==============
     'これはEnum宣言と同じく作っておく
     Private Function GetName( ByVal Type As Type, ByVal Code As Integer ) As String

        Dim tmp As String = Nothing

        If Type Is GetType(ABCD) Then
            Select Case Code
                Case ABCD.A.GetHashCode
                    tmp = "えー"
                Case ABCD.B.GetHashCode
                    tmp = "びー"
                Case ABCD.C.GetHashCode
                    tmp = "しー"
                Case ABCD.D.GetHashCode
                   tmp = "でー"
            End Select
        End If

        Return tmp

    End Function

# End Region

'たとえば列挙したデータでデータテーブルを作りたい場合==============
  Dim dt As New DataTable
  dt.Columns.Add( "id" , GetType( Integer))
  dt.Columns.Add( "name" , GetType( String))
  For Each EnumNumber As ABCDIn System.Enum.GetValues(GetType (ABCD))
        Dim dr As DataRow = dt.NewRow
        dr.Item( "id" ) = EnumNumber
        dr.Item( "name" ) = GetName( GetType(ABCD), EnumNumber)
        dt.Rows.Add(dr)
  Next

2012年4月19日木曜日

[.NET]Hashテーブルを使ったクラス

From Evernote:

[.NET]Hashテーブル(辞書)を使ったクラス

Hashテーブル(dictionary型)を使ったクラスを持っておいて
1度宣言すれば
ループ時等で何度もマスタ読みに行かなくてラク。


'本文では==================================

Dim GetTanto As New GetTanto  '宣言

Dim TestArray(3) = {1000,2000,3000} 
For As Integer = 0 To TestTrray.Length - 1
   debug GetTanto.GetName(TestArray(i)) '表示
Next


'クラスは=======================================

'class_担当者をとってくる -------
Public Class GetTanto

# Region "Member"
        Private NameTBL As New System.Collections.Generic.Dictionary(Of Integer , String)
# End Region
# Region "Constructor"
        Sub New ()
            MyClass.ReadMaster()
        End Sub
# End Region
# Region "ReadMaster"
        Sub ReadMaster()

            Dim strSQL As String = "SELECT * from M_ 担当者"
            Dim objDS As New DataSet
            ADONET.FillDataset(STRCON, objDS, "Table" , strSQL)
            For i As Integer = 0 To objDS.Tables("Table").Rows.Count - 1
                With objDS.Tables("Table").Rows(i)
                    NameTBL.Add(.Item( "担当コード "), .Item( "担当者"))
                End With
            Next

        End Sub
# End Region
# Region "GetName"
        Public Function GetName( ByVal No As Object) As String

            Dim tmp As String = ""
            '合致するなら
            If NameTBL.ContainsKey(No) Then
               tmp = NameTBL(No).ToString.Trim
            End If
            Return tmp

        End Function
# End Region

End Class