Sì è fattibile, avevo realizzato qualcosa di simile solo che al posto di testi muovevo dei rettangoli. L'ideale sarebbe quello di realizzare un usercontrol, ma puoi anche continuare ad utilizzare la PictureBox, non ci dovrebbero essere particolari problemi.
Per comodità dovresti tenere un array (o una lista) di oggetti di tipo "Scritta", che contiene il testo della scritta, le coordinate e la dimensione del carattere:
codice:
Public Class Scritta
Public Property Testo() As String
Public Property Posizione() As Point
Public Property Carattere() As Byte
End Class
Private lista As New List(Of Scritta)
'queste variabili servono per realizzare il drag & drop
Private start As Point
Private moving As Scritta
Iterando sugli elementi della lista non ti sarà difficile disegnare le scritte:
codice:
For Each s As Scritta In lista
e.Graphics.DrawString(...)
Next
Per gestire il drag&drop bisogna innanzitutto determinare quale elemento della lista è stato cliccato. Potresti scrivere una funzione come questa:
codice:
Private Function HitTest(ByVal x As Integer, ByVal y As Integer) As Scritta
Dim ret As Scritta = Nothing
Dim r As Rectangle
Dim g As Graphics = CreateGraphics()
Dim sz As SizeF
For Each s As Scritta In lista
'determina le dimensioni della scritta
sz = g.MeasureString(s.Testo, New Font(Me.Font.FontFamily, s.Carattere))
'crea un rettangolo con la stessa posizione e dimensione della scritta
r = New Rectangle(s.Posizione, sz.ToSize)
'verifica se il punto (x, y) è contenuto nel rettangolo
If r.Contains(x, y) Then ret = s
Next
Return ret
End Function
Nell'evento MouseDown:
codice:
moving = HitTest(e.X, e.Y)
start = New Point(e.X, e.Y)
Nell'evento MouseMove:
codice:
If moving IsNot Nothing Then
moving.Posizione = New Point(moving.Posizione.X + (e.X - start.X), moving.Posizione.Y + (e.Y - start.Y))
start = New Point(e.X, e.Y)
Me.Invalidate()
End If
Nell'evento MouseUp: