none
DragDrop между TableLayoutPanel в VB RRS feed

  • Вопрос

  • Добрый вечер.

    Никак не могу решить следующую задачу:

    Необходимо сделать DragDrop м-у TableLayoutPanel. В панели 1 находятся кнопки (Button), вторая пустая. Так как ни один из примеров не получилось запустить из найденных в интернете, вопрос - как вообще это сделать? 

    Заранее благодарю.

    17 марта 2011 г. 17:20

Ответы

  • Вроде все работает, но хотелось бы при перетаскивании видеть перетаскиваемую кнопку а не курсор.

     

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      TableLayoutPanel2.AllowDrop = True
     End Sub
     Public Sub New()
      InitializeComponent()
      For Each but As Button In TableLayoutPanel1.Controls
       AddHandler but.MouseDown, AddressOf but_MouseDown
      Next
     End Sub
     Private Sub but_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim but As Button = CType(sender, Button)
      but.DoDragDrop(but, DragDropEffects.Copy)
     End Sub
     Private Sub TableLayoutPanel2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragEnter
      If (e.Data.GetDataPresent(DataFormats.Serializable)) Then
       e.Effect = DragDropEffects.Copy
      Else
       e.Effect = DragDropEffects.None
      End If
     End Sub
     Private Sub TableLayoutPanel2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragDrop
      Dim but As Button = CType(e.Data.GetData(DataFormats.Serializable), Button)
      TableLayoutPanel2.Controls.Add(but, -1, -1)
      but.Location = TableLayoutPanel2.PointToClient(New Point(e.X, e.Y))
      but.BringToFront()
     End Sub
    

     

    • Помечено в качестве ответа erekoze 18 марта 2011 г. 10:29
    17 марта 2011 г. 21:39
  • Это происходит потому, что происходит поверхностное копирование кнопки, т.е. копируется только ссылка на объект, а не полностью объект. В итоге при вставки имеем туже самую кнопку. А контрол не может находится в нескольких контейнерах одновременно, поэтому кнопка и вырезается из первого. Вам нужно перед драг-дропом создать новую кнопку и скопировать нужные свойства старой. Полное копирование можете посмотреть здесь - Как полностью копировать контрол winForms?. Если возникнут трудности с переводом на vb.net - пишите.

     


    Для связи [mail]
    • Помечено в качестве ответа erekoze 18 марта 2011 г. 10:29
    18 марта 2011 г. 8:26

Все ответы

  • Нашел здесь пример, как это делается, но опять застрял :(

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        TableLayoutPanel2.AllowDrop = True
     End Sub
     Public Sub New()
        InitializeComponent()
        For Each but As Button In TableLayoutPanel1.Controls
          AddHandler but.MouseDown, AddressOf but_MouseDown
        Next
     End Sub
     Private Sub but_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim but As Button = CType(sender, Button)
        but.DoDragDrop(but, DragDropEffects.Copy)
     End Sub
     Private Sub TableLayoutPanel2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragEnter
        If (e.Data.GetDataPresent(DataFormats.Serializable)) Then
          e.Effect = DragDropEffects.Copy
        Else
          e.Effect = DragDropEffects.None
        End If
     End Sub
     Private Sub TableLayoutPanel2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragDrop
        Dim but As Button = CType(e.Data.GetData(DataFormats.Serializable), Button)
        TableLayoutPanel2.Controls.Add(but)
     End Sub
    

    проблема знаю в чем , e.Data.GetDataPresent(DataFormats.Serializable) а вот как исправить...

    17 марта 2011 г. 18:49
  • ну что то получилось, подсмотрел как сделано в шарпе, 

    Dim but As Button = CType(e.Data.GetData(GetType(Button)), Button)

    сейчас разобраться только осталось с перемещением кнопки.

    17 марта 2011 г. 19:38
  • Вроде все работает, но хотелось бы при перетаскивании видеть перетаскиваемую кнопку а не курсор.

     

     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      TableLayoutPanel2.AllowDrop = True
     End Sub
     Public Sub New()
      InitializeComponent()
      For Each but As Button In TableLayoutPanel1.Controls
       AddHandler but.MouseDown, AddressOf but_MouseDown
      Next
     End Sub
     Private Sub but_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
      Dim but As Button = CType(sender, Button)
      but.DoDragDrop(but, DragDropEffects.Copy)
     End Sub
     Private Sub TableLayoutPanel2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragEnter
      If (e.Data.GetDataPresent(DataFormats.Serializable)) Then
       e.Effect = DragDropEffects.Copy
      Else
       e.Effect = DragDropEffects.None
      End If
     End Sub
     Private Sub TableLayoutPanel2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragDrop
      Dim but As Button = CType(e.Data.GetData(DataFormats.Serializable), Button)
      TableLayoutPanel2.Controls.Add(but, -1, -1)
      but.Location = TableLayoutPanel2.PointToClient(New Point(e.X, e.Y))
      but.BringToFront()
     End Sub
    

     

    • Помечено в качестве ответа erekoze 18 марта 2011 г. 10:29
    17 марта 2011 г. 21:39
  • и еще недостаток - исчезает кнопка в источнике :(. хоть и выставлен e.Effect = DragDropEffects.Copy
    17 марта 2011 г. 21:42
  • Это происходит потому, что происходит поверхностное копирование кнопки, т.е. копируется только ссылка на объект, а не полностью объект. В итоге при вставки имеем туже самую кнопку. А контрол не может находится в нескольких контейнерах одновременно, поэтому кнопка и вырезается из первого. Вам нужно перед драг-дропом создать новую кнопку и скопировать нужные свойства старой. Полное копирование можете посмотреть здесь - Как полностью копировать контрол winForms?. Если возникнут трудности с переводом на vb.net - пишите.

     


    Для связи [mail]
    • Помечено в качестве ответа erekoze 18 марта 2011 г. 10:29
    18 марта 2011 г. 8:26
  • Спасибо за подсказку, сейчас буду химичить. Еще вопрос сразу - а как сделать, что бы переносимая кнопка отображалась именно кнопкой при переносе а не как смена вида курсора, по аналогии с тем же перемещением панелей в самой среде Visual Studio?
    18 марта 2011 г. 10:29
  • Остановился на варианте создания новой кнопки , и копировании нужных свойств.

     

    Private Sub TableLayoutPanel2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TableLayoutPanel2.DragDrop
     Dim but As Button = CType(e.Data.GetData(DataFormats.Serializable), Button)
    dim but2 as new button
     with but2
     'здесь копируем нужные свойства из but
     end with
     TableLayoutPanel2.Controls.Add(but2, -1, -1)
    End Sub
    

     

    Теперь буду искать способ анимировать перемещение кнопки.

     


    18 марта 2011 г. 17:21
  • Нашел кстати реализацию создания копии контрола для VB, может пригодится кому.

     

    Imports System.Reflection
    Private Function CloneControl(ByVal control As Object) As Object
      Dim type As Type = control.GetType()
      Dim properties As PropertyInfo() = type.GetProperties()
      Dim retObject As Object = type.InvokeMember("", System.Reflection.BindingFlags.CreateInstance, Nothing, control, Nothing)
      For Each p As PropertyInfo In properties
       If p.CanWrite Then
        p.SetValue(retObject, p.GetValue(control, Nothing), Nothing)
       End If
      Next
      Return retObject
    End Function
    

     

     


    18 марта 2011 г. 17:31