Grazie e scusa se non ho risposto subito, volevo scrivere "ci sono riuscito!" ma in realtà mi sono incartato....programmo per hobby ed inoltre non mi sono impegnato molto sul tuo codice... ...ne comprendo o intuisco il perchè ma senza un' esempio "funzionante" faccio fatica, buona parte del codice non l' ho mai utilizzato.
Comunque credo mi convenga la strada dell' usercontrol, mi porterebbe numerosi vantaggi:

1 aggiungere righe, linee e rettangoli a runtime superando il limite attuale di 10
2 farei sparire tutti quei textbox e numericupdown sulla sinistra migliorando l' aspetto e l' usabilità
3 mi semplificherebbe la creazione del codice ZPL per stampare l' etichetta
4 il codice sarà più elastico da modificare e gestire
5 sicuramente mi stà sfuggendo qualche altro pregio...

Attualmente, in linea di massima, il programma funziona così:
all' avvio del form recupero i dpi del sistema, imposto un valore che rappresenta i dpi della stampante, li divido per ottenere un rapporto che mi servirà per lo ZPL, eseguo un calcolo aritmetico per convertire dpi, pollici e millimetri in modo da dimensionare la picturebox alle dimensioni fisiche dell' etichetta;

con la modifica di testo, posizione e dimensione carattere (sub riga1 e riga1_1) si avvia la Sub (scrivi) che crea o aggiorna il testo sulla picturbox, a causa dei diversi font e dal diverso utilizzo di posizionamento tra Windows e la Zebra sono costretto ad inserire una variabile (ct1Diff) per ottenere un' anteprima fedele all' etichetta stampata perchè le coordinate in Windows tengono conto della spaziatura del carattere che aumenta con l' aumentare della dimensione del carattere mentre la Zebra no, per esempio in Windows un carattere dim. 10x10 con spaziatura 5 ha la posizione 15,15 mentre per la Zebra rimane 10,10, quando eseguo il DrawString sottraggo al numericupdown della posizione un valore ct1Diff ottenuto dall' altezza del font diviso per un valore (interlinea) ottenuto dopo diverse prove;

al click sul button della stampa eseguo nuovamente un' operazione aritmetica per adattare le coordinate del testo in dpi tra Windows e Zebra, poi inserisco i valori di posizione, dimensione e testo in una stringa di codice ZPL e avvio la stampa.
Per completezza il codice ZPL per stampare CIAO è:
codice:
' inizio codice
^XA

' 20,20 posizione X Y, 25 dimensione font
^FO20,20^A0N,25^FDciao^FS

'1 numero di etichette da stampare
^PQ1

'fine codice
^XZ
il codice sopra va scritto in un txt esclusi i commenti in stile VB è stampato sulla Zebra installata come "Generic/Text Only".
Il codice di seguito è un' esempio per stampare una singola riga di testo, nel programma effettivo è moltiplicato per 10 oltre a qualcosa di simile (sempre x10) per disegnare rettangoli e linee inoltre tutte le variabili sono modificabili inclusa la dimensione dell' etichetta/picturebox.
codice:
Imports System.IO
Imports System.Text

Public Class Form1

    Dim interlinea As Decimal = CDec(1.8) ' valore approssimativo ottenuto da prove
    Dim miofont As String        ' lo lascio vuoto, usa il font di sistema...
    Dim ct1 As Single = 20       ' imposto un valore se no si incatasta
    Dim ct1Diff As Single = 1    ' imposto un valore se no si incatasta
    Dim rapporto_dpi As Decimal  ' rapporto tra dpi stampante/sistema
    Dim dpi_sistema As Decimal   ' dpi di windows
    Dim dpi_stampante As Decimal ' dpi stampante
    Dim etichetta As String      ' contenitore dello ZPL

    Private Sub Form1_Load() Handles MyBase.Load
        ' ottengo i dpi del sistema
        Dim g As Graphics = Me.CreateGraphics
        dpi_sistema = CDec(g.DpiX) 'Pixels per Inch
        g.Dispose()

        'calcolo il rapporto dpi
        dpi_stampante = 200
        rapporto_dpi = System.Math.Round(dpi_stampante / dpi_sistema)

        'imposto la dimensione della picturebox per rispecchiare
        'un' etichetta dalle dimensioni 110mm x 80mm
        PictureBox1.Width = CInt(System.Math.Round(110 * dpi_sistema / 25.4))
        PictureBox1.Height = CInt(System.Math.Round(80 * dpi_sistema / 25.4))
      
    End Sub

    Private Sub scrivi()
        PictureBox1.Refresh()

        Dim riga1 As Graphics = PictureBox1.CreateGraphics()
        Dim drawFont1 As New Font(miofont, ct1, FontStyle.Bold)
        ct1Diff = CSng(System.Math.Round(drawFont1.GetHeight / interlinea))
        riga1.DrawString(TextBox1.Text, drawFont1, Brushes.Black, _
        NumericUpDown_testo_X_1.Value - ct1Diff, _
        NumericUpDown_testo_Y_1.Value - ct1Diff)

    End Sub

    ' aggiorna la posizione del testo nell' anteprima
    Private Sub riga1() Handles TextBox1.TextChanged, NumericUpDown_testo_X_1.ValueChanged, _
        NumericUpDown_testo_Y_1.ValueChanged, NumericUpDown_car_1.ValueChanged
        scrivi()
    End Sub

    ' aggiorna la dimensione del testo nell' anteprima
    ' l' evento non è nella sub riga1 perchè altrimenti genera un' eccezione
    Private Sub riga1_1() Handles NumericUpDown_car_1.ValueChanged
        ct1 = NumericUpDown_car_1.Value
        scrivi()
    End Sub

    ' pezza per evitare sparizioni e apparazioni...
    Private Sub riscrivi() Handles Me.Paint
        scrivi()
    End Sub

    Private Sub crea_zpl() Handles Button1.Click
        Dim x91 As String = CStr(System.Math.Round(NumericUpDown_testo_X_1.Value * rapporto_dpi - ct1Diff))
        Dim y91 As String = CStr(System.Math.Round(NumericUpDown_testo_Y_1.Value * rapporto_dpi - ct1Diff))
        Dim c91 As String = CStr(System.Math.Round(NumericUpDown_car_1.Value * rapporto_dpi + ct1Diff))

        etichetta = "^XA" & vbCrLf & _
      "^FO" & x91 & "," & y91 & "^A0N," & c91 & "^FD" & TextBox1.Text & "^FS" & vbCrLf & _
      "^PQ1" &
      "^XZ"
        ' poi stampo
    End Sub
End Class
Scusate la lunghezza del post.

Vincenzo