Slepen / Drag & Drop

Status
Niet open voor verdere reacties.

gille

Gebruiker
Lid geworden
19 okt 2009
Berichten
76
Na lang zoeken, niets gevonden...

Ik heb een formulier en ik heb enkele objecten (labels, buttons, ...) erop geplaatst.
Nu, de gebruiker zou die objecten moeten kunnen slepen over het formulier.
Zijn eigen layout kiezen eigenlijk.

Hoe doe ik dit?

(Alvast bedankt!)
 
Code:
    Dim IsDragging As Boolean
    Dim StartX, StartY As Integer

    Private Sub Mouse_Down(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles Button1.MouseDown, Label1.MouseDown

        IsDragging = True
        StartX = e.X
        StartY = e.Y

    End Sub

    Private Sub Mouse_Move(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles Button1.MouseMove, Label1.MouseMove

        If IsDragging = True Then
            sender.Location = New Point(sender.Location.X + e.X - StartX, sender.Location.Y + e.Y - StartY)
        End If

    End Sub

    Private Sub Mouse_Up(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
    Handles Button1.MouseUp, Label1.MouseUp

        IsDragging = False

    End Sub

Als je nog meer controls wilt verplaatsen, voeg je ze toe aan de regel Handles... voor alle drie de subs.
 
Laatst bewerkt:
Enorm bedankt The Mighty Atom! :D

Een heel hoop werk bespaard. Ik wil het niet te moeilijk maken, maar...

(met een voorbeeld) als je buttons en labels versleept, staan ze in een andere positie.
Je sluit het programma af en wanneer je het terug opstart zouden die buttons op dezelfde plaats moeten staan als wanneer er werd afgesloten. Hoe kan je het dit best doen in VB?
 
De locaties tijdens het unloaden van je form opslaan. Dit kan je doen door naar het register te schrijven, bijvoorbeeld. Maar ook door een bestand aan te maken en daar de locaties in te schrijven.

Dan kan je ze tijdens het laden weer opvragen en goed zetten!



:thumb:
 
De locaties tijdens het unloaden van je form opslaan. Dit kan je doen door naar het register te schrijven, bijvoorbeeld. Maar ook door een bestand aan te maken en daar de locaties in te schrijven.

Dan kan je ze tijdens het laden weer opvragen en goed zetten!



:thumb:

Helaas ben ik nog een beginner, maar hoe doe je dat precies met dat register?
Is dat iets bij Properties?
 
Persoonlijk zou ik kiezen voor een tekst bestandje waarin je de locatie van alle controls in opslaat. Daarmee loop je geen risico dat je je register sloopt, wat zowiezo een kleine kans is, maar toch.

Ik zal wel ff wat proberen voor je.
 
Ok, ik denk dat ik het heb.

Om te beginnen moet je een module aan je project toevoegen. Ik neem aan dat je weet hoe dat moet.

Plaats de volgende code in de module (de code die automatisch in de module worden geplaats kun je overschijven):

Code:
Imports System.Collections.Hashtable

Module Module1

    Dim myHashes As Hashtable

    Sub BuildHashTable(ByVal myControl As Control, Optional ByVal isInit As Boolean = True)
        If isInit Then
            If myHashes Is Nothing Then myHashes = New Hashtable(myControl.Controls.Count)
            myHashes.Clear()
        End If
        Dim i%
        Dim c As New Control
        If myControl Is Nothing Then Exit Sub
        If myControl.Controls Is Nothing Then Exit Sub
        If myControl.Controls.Count <= 0 Then Exit Sub
        For i = 0 To myControl.Controls.Count - 1
            myHashes.Add(myControl.Controls(i).Name, myControl.Controls(i))
            BuildHashTable(myControl.Controls(i), False)
        Next
    End Sub

    Sub SetProperty(ByVal myObject As Object, ByVal Prop As String)
        If myObject Is Nothing Then Exit Sub
        Dim s$
        Try
            s = Prop
            If s <> Nothing Then
                Select Case myObject.GetType.ToString

                    Case "System.Windows.Forms.Button"
                        Dim strArr() As String
                        strArr = s.Split("-")
                        myObject.Location = New Point(strArr(0), strArr(1))

                    Case "System.Windows.Forms.Label"
                        Dim strArr() As String
                        strArr = s.Split("-")
                        myObject.Location = New Point(strArr(0), strArr(1))

                End Select
            End If
        Catch ex As System.Exception

        End Try
    End Sub

    Sub LoadControls(ByVal me1 As Control)
        Dim key$, value$
        Dim o As Control
        While Not EOF(FileNo)
            Try
                key = LInput(FileNo)
                o = myHashes.Item(key)
                value = LInput(FileNo)
                SetProperty(o, value)
            Catch ex As System.Exception
                FClose(FileNo)
                Throw New System.Exception(ex.Message)
            End Try
        End While
    End Sub

    Sub SaveControls(ByVal me1 As Control)
        Dim c As Object
        Dim i%
        If me1 Is Nothing Then Exit Sub
        If me1.Controls Is Nothing Then Exit Sub
        If me1.Controls.Count <= 0 Then Exit Sub
        For i = 0 To me1.Controls.Count - 1
            c = me1.Controls(i)
            Try
                Select Case c.GetType.ToString

                    Case "System.Windows.Forms.Button"
                        RSet(c.name, c.location.x & "-" & c.location.y)

                    Case "System.Windows.Forms.Label"
                        RSet(c.name, c.location.x & "-" & c.location.y)

                End Select
            Catch ex As System.Exception

            End Try
            SaveControls(me1.Controls(i))
        Next
    End Sub

    Public Sub SaveSettings(ByVal Cntl As Control, ByVal File$)
        FileNo = FOpen(File, OpenMode.Output)
        If FileNo = -1 Then Throw New System.Exception("File - " + File + " cannot be opened for writing!")
        BuildHashTable(Cntl)
        SaveControls(Cntl)
        FClose(FileNo)
    End Sub

    Public Sub LoadSettings(ByVal Cntl As Control, ByVal File$)
        FileNo = FOpen(File)
        If FileNo = -1 Then Throw New System.Exception("File - " + File + " cannot be opened for reading!")
        BuildHashTable(Cntl)
        LoadControls(Cntl)
        FClose(FileNo)
    End Sub

    Dim FileNo% = -1

    Private Sub RSet(ByVal Key$, ByVal Value$)
        Print(FileNo, Key & vbCrLf)
        Print(FileNo, Value & vbCrLf)
    End Sub

    Public Function FOpen(ByVal File$, Optional ByVal Mode As Microsoft.VisualBasic.OpenMode = OpenMode.Input) As Integer
        FOpen = FreeFile()
        Try
            FileOpen(FOpen, File, Mode)
        Catch ex As System.Exception
            Try
                FileClose(FOpen)
            Catch ex2 As System.Exception

            End Try
            Return -1
        End Try
    End Function

    Public Function FClose(ByVal FILE%) As Integer
        Try
            FileClose(FILE)
        Catch ex As System.Exception
            Return -1
        End Try
        Return 0
    End Function
    Public Function LInput(ByVal FILE%, Optional ByVal STR$ = "Error - Cannot read another line from file ") As String
        Try
            LInput = LineInput(FILE)

        Catch ex As System.Exception
            Throw New System.Exception(STR)
        End Try
    End Function

End Module

Dan op je main form:

Code:
Private Sub Form1_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing

        SaveSettings(Me, Application.StartupPath & "\ControlLocations.txt")

    End Sub

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

        If IO.File.Exists(Application.StartupPath & "\ControlLocations.txt") Then
            LoadSettings(Me, Application.StartupPath & "\ControlLocations.txt")
        End If

    End Sub

En dat is het. Ik heb het alleen getest met een button en een label, als je meerdere controls wilt laten opslaan, moet je een klein stukje code in de module bij plaatsen, kijk goed naar de code voor de label en de button, kopieer het en plaats het erbij.

Als het niet lukt, laat het weten.

Succes!
 
Bedankt! Leuk dat je je tijd hier in wilt steken! ;)

Ik kan met dit wel verder om enkele extra's te maken.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan