Sincronizzare la scrollbar di due RichTextBox

Talvolta in applicazioni .NET WinForms (Windows Forms) potrebbe essere utile sincronizzare la scrollbar verticale di due RichTextBox ad esempio se si vuole realizzare un semplice visualizzatore di testo che abbia la funzionalità di mostrare anche il numero di riga. Un semplice visualizzatore di questo tipo può essere realizzato, ad esempio, tramite due RichTextBox, uno che visualizza il numero di riga e uno che visualizza il testo.

Di seguito un esempio di visualizzatore di questo tipo che ho scritto nell’ambito l’applicazione .NET WinForms PowerTray che sto sviluppando a tempo perso e che ha l’obbiettivo di poter eseguire script PowerShell e di visualizzare l’output quando lo si desidera tramite una un’icona nella tray bar.

Affinché i due RichTextBox siano funzionali allo scopo della visualizzazione del testo mantenendo il corretto riferimento al numero della riga la scrollbar verticale del RichTextBox che mostra il numero di riga (denominato rtbLineNumbers) deve essere sincronizzata con la vertical scrollbar del richtextbox che mostra il testo (denominato rtbScriptText). Ovvero quando si esegue uno scroll verticale sul richtextbox che mostra il testo (denominato rtbScriptText) questo deve essere replicato la scrollbar verticale del RichTextBox che mostra il numero di riga (denominato rtbLineNumbers).

Di seguito il codice VB.NET che può essere utilizzato per realizzare tale comportamento che utilizza la funzione API SendMessage per leggere e impostare la posizione della scrollbar:

<System.Runtime.InteropServices.DllImport(“user32.dll”)>

Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Int32, ByVal wParam As Int32, ByRef lParam As System.Drawing.Point) As Int32

End Function

 

Private Sub rtbScriptText_VScroll(sender As Object, e As EventArgs) Handles rtbScriptText.VScroll

Const WM_USER As Integer = &H400

Const EM_GETSCROLLPOS As Integer = WM_USER + 221

Const EM_SETSCROLLPOS As Integer = WM_USER + 222

 

Dim currentScrollPosition As Point

ScriptPreviewForm.SendMessage(Me.rtbScriptText.Handle, EM_GETSCROLLPOS, 0, currentScrollPosition)

ScriptPreviewForm.SendMessage(Me.rtbLineNumbers.Handle, EM_SETSCROLLPOS, 0, currentScrollPosition)

End Sub