トップ回答者
DataGridViewからTreeViewにドラッグドロップするには

質問
回答
-
原因としては、複数行を選択していたとしても、以下の箇所
DoDragDrop(DataGridView1.Rows(hit.RowIndex), DragDropEffects.Move)
で、一行分しかドラッグドロップ対象のデータとして設定していない為です。
DoDragDropには、「Me.DataGridView1.SelectedRows()」を渡すと良いです。
一応確認のために書いたコードがあるので、参考として利用してください。
前提は、フォームにDataGridView1とTreeView1を貼り付けるだけです。
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' TreeView初期データを作成 TreeView1.Nodes.Add("あ") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("い") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("う") TreeView1.Nodes.Add("か") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("き") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("く") TreeView1.Nodes.Add("さ") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("し") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("す") ' DataGridView初期データを作成 Me.DataGridView1.Columns.Add("column1", "column1") Me.DataGridView1.Columns.Add("column2", "column2") For i As Integer = 1 To 10 Me.DataGridView1.Rows.Add("1_" + i.ToString(), "2_" + i.ToString()) Next 'TreeView1へドラッグを許可 TreeView1.AllowDrop = True ' Drag&Drop関連のイベントを登録 AddHandler DataGridView1.MouseDown, AddressOf DataGridView1_MouseDown AddHandler TreeView1.DragOver, AddressOf TreeView1_DragOver AddHandler TreeView1.DragDrop, AddressOf TreeView1_DragDrop End Sub Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) ' 左クリックの場合のみ処理 If e.Button = MouseButtons.Left Then ' DataGridView1の行選択が存在すること If Me.DataGridView1.SelectedRows().Count > 0 Then ' 行選択全てをドラッグドロップデータに設定 Me.DataGridView1.DoDragDrop(Me.DataGridView1.SelectedRows(), DragDropEffects.Copy) End If End If End Sub Private Sub TreeView1_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) ' DataGridViewSelectedRowCollection以外は受け入れない If e.Data.GetDataPresent(GetType(DataGridViewSelectedRowCollection)) Then e.Effect = DragDropEffects.Copy ' DropするNodeを取得する Dim p As Point = Me.TreeView1.PointToClient(New Point(e.X, e.Y)) Dim target As TreeNode = Me.TreeView1.GetNodeAt(p) If Not target Is Nothing Then ' DropするNodeを選択する Me.TreeView1.Focus() If target.IsSelected = False Then Me.TreeView1.SelectedNode = target End If ' 選択するNodeが子を持っている場合は展開 If target.Nodes.Count > 0 And Not target.IsExpanded Then target.Expand() End If Else e.Effect = DragDropEffects.None End If Else e.Effect = DragDropEffects.None End If End Sub Private Sub TreeView1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) ' DataGridViewSelectedRowCollection以外は受け入れない If e.Data.GetDataPresent(GetType(DataGridViewSelectedRowCollection)) Then ' DataGridView1の行選択データを取得 Dim data As DataGridViewSelectedRowCollection = CType(e.Data.GetData( _ GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection) ' もし複数行の追加データを特定の順序で追加する必要があれば ' ここでdataをソートする ' Drop先のNodeの子Nodeとして、DataGridView1の行選択データを追加 For Each row As DataGridViewRow In data ' column1とcolumn2の文字列を結合して追加する Me.TreeView1.SelectedNode.Nodes.Add(row.Cells(0).Value.ToString() + ":" + _ row.Cells(1).Value.ToString()) Next Else e.Effect = DragDropEffects.None End If End Sub End Class
- 回答としてマーク 山本春海 2010年12月10日 2:31
すべての返信
-
ご回答ありがとうございます。
仰られている通り、「SelectedRows」を使って出来そうかなと思っていたのですが
データの受け渡しの部分でうまく動きませんでした。
(下記にしたりしました。
DoDragDrop(DataGridView1.SelectedRows, DragDropEffects.Move)
)DataGridViewのマウスダウンイベント(DataGridView1_MouseDown)で選択されたレコードを取得し
TreeViewのドラックドロップイベント(TreeView1_DragDrop)の引数
「ByVal e As System.Windows.Forms.DragEventArgs」で受け取った時
選択された複数レコードにしたいです。(現在は1レコードだけ)
如何せん、Web上のサンプルを理解できず作ったプログラムなので
改変が出来ませんでした。
お手数をお掛けしますが、宜しくお願いします。
■受け渡しのソース抜粋しました。
Private Sub DataGridView1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown
Dim hit As DataGridView.HitTestInfo = DataGridView1.HitTest(e.X, e.Y)
If hit.Type = DataGridViewHitTestType.Cell AndAlso (Me.DataGridView1.NewRowIndex = -1 OrElse Me.DataGridView1.NewRowIndex <> hit.RowIndex) Then
DoDragDrop(DataGridView1.Rows(hit.RowIndex), DragDropEffects.Move)
End If
End SubPrivate Sub TreeView1_DragDrop(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView1.DragDrop
Dim strNode As String
Dim pt As Point
Dim DestinationNode As TreeNode
pt = CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
DestinationNode = CType(sender, TreeView).GetNodeAt(pt)' ドロップするデータ
Dim dgvr As DataGridViewRow = DirectCast(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow)'ノード名を取得する
strNode = ""
For col As Integer = 0 To dgvr.Cells.Count - 1
strNode = strNode & dgvr.Cells(col).Value
Next'選択されたノードを追加する
Dim NewNode As New TreeNode(strNode)'親ツリーにノードを追加する
DestinationNode.Nodes.Add(NewNode.Clone)
DestinationNode.Expand()End Sub
-
原因としては、複数行を選択していたとしても、以下の箇所
DoDragDrop(DataGridView1.Rows(hit.RowIndex), DragDropEffects.Move)
で、一行分しかドラッグドロップ対象のデータとして設定していない為です。
DoDragDropには、「Me.DataGridView1.SelectedRows()」を渡すと良いです。
一応確認のために書いたコードがあるので、参考として利用してください。
前提は、フォームにDataGridView1とTreeView1を貼り付けるだけです。
Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' TreeView初期データを作成 TreeView1.Nodes.Add("あ") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("い") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("う") TreeView1.Nodes.Add("か") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("き") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("く") TreeView1.Nodes.Add("さ") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("し") TreeView1.Nodes(TreeView1.Nodes.Count - 1).Nodes.Add("す") ' DataGridView初期データを作成 Me.DataGridView1.Columns.Add("column1", "column1") Me.DataGridView1.Columns.Add("column2", "column2") For i As Integer = 1 To 10 Me.DataGridView1.Rows.Add("1_" + i.ToString(), "2_" + i.ToString()) Next 'TreeView1へドラッグを許可 TreeView1.AllowDrop = True ' Drag&Drop関連のイベントを登録 AddHandler DataGridView1.MouseDown, AddressOf DataGridView1_MouseDown AddHandler TreeView1.DragOver, AddressOf TreeView1_DragOver AddHandler TreeView1.DragDrop, AddressOf TreeView1_DragDrop End Sub Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) ' 左クリックの場合のみ処理 If e.Button = MouseButtons.Left Then ' DataGridView1の行選択が存在すること If Me.DataGridView1.SelectedRows().Count > 0 Then ' 行選択全てをドラッグドロップデータに設定 Me.DataGridView1.DoDragDrop(Me.DataGridView1.SelectedRows(), DragDropEffects.Copy) End If End If End Sub Private Sub TreeView1_DragOver(ByVal sender As Object, ByVal e As DragEventArgs) ' DataGridViewSelectedRowCollection以外は受け入れない If e.Data.GetDataPresent(GetType(DataGridViewSelectedRowCollection)) Then e.Effect = DragDropEffects.Copy ' DropするNodeを取得する Dim p As Point = Me.TreeView1.PointToClient(New Point(e.X, e.Y)) Dim target As TreeNode = Me.TreeView1.GetNodeAt(p) If Not target Is Nothing Then ' DropするNodeを選択する Me.TreeView1.Focus() If target.IsSelected = False Then Me.TreeView1.SelectedNode = target End If ' 選択するNodeが子を持っている場合は展開 If target.Nodes.Count > 0 And Not target.IsExpanded Then target.Expand() End If Else e.Effect = DragDropEffects.None End If Else e.Effect = DragDropEffects.None End If End Sub Private Sub TreeView1_DragDrop(ByVal sender As Object, ByVal e As DragEventArgs) ' DataGridViewSelectedRowCollection以外は受け入れない If e.Data.GetDataPresent(GetType(DataGridViewSelectedRowCollection)) Then ' DataGridView1の行選択データを取得 Dim data As DataGridViewSelectedRowCollection = CType(e.Data.GetData( _ GetType(DataGridViewSelectedRowCollection)), DataGridViewSelectedRowCollection) ' もし複数行の追加データを特定の順序で追加する必要があれば ' ここでdataをソートする ' Drop先のNodeの子Nodeとして、DataGridView1の行選択データを追加 For Each row As DataGridViewRow In data ' column1とcolumn2の文字列を結合して追加する Me.TreeView1.SelectedNode.Nodes.Add(row.Cells(0).Value.ToString() + ":" + _ row.Cells(1).Value.ToString()) Next Else e.Effect = DragDropEffects.None End If End Sub End Class
- 回答としてマーク 山本春海 2010年12月10日 2:31
-
こんにちは、basser819 さん。
MSDN フォーラムのご利用ありがとうございます。オペレーターの山本です。
問題が解決したとのこと、よかったですね。
honefai さんからの投稿が参考になったようでしたので、勝手ながら私のほうで回答としてマークさせていただきました。
honefai さん、アドバイスありがとうございます。
今後同じ問題でこのスレッドを参照される方にも有効な情報が分かりやすくなるかと思いますので、解決に役立った有効な情報や参考になった情報には、回答としてマークすることをお願いしています。
ご協力よろしくお願いいたしますね。
今後とも、MSDN フォーラムをよろしくお願いいたします。
マイクロソフト株式会社 フォーラム オペレーター 山本 春海