Top Features to Add to Your VB .NET Notepad Application

VB .NET Notepad: Implementing Syntax Highlighting and Line Numbers

Creating a Notepad-like application in VB .NET is a great way to learn Windows Forms and text handling. Adding syntax highlighting and line numbers makes it far more useful for code editing. This article walks through a concise, practical implementation using Windows Forms (WinForms) and a RichTextBox control with minimal external dependencies.

Overview

  • Goal: A simple Notepad with syntax highlighting for a chosen language (example: VB.NET keywords) and a live line-number gutter.
  • Approach: Use a RichTextBox for editable text, a Panel/Label or a separate read-only RichTextBox for the line-number gutter, and a keyword-based highlighting routine that updates on text changes and caret moves.
  • Assumptions: Targeting .NET Framework or .NET (Windows) with WinForms; familiarity with VB .NET and basic event handling.

Project setup

  1. Create a new Windows Forms App (VB .NET).
  2. Add controls to the main form:
    • RichTextBox named rtbEditor (Dock = Fill).
    • Panel named pnlGutter docked Left to host line numbers (Width ≈ 50).
    • (Optional) A read-only RichTextBox named rtbGutter inside pnlGutter for easier synchronization.
  3. Set rtbEditor.AcceptsTab = True, rtbEditor.Font to a monospaced font (e.g., Consolas).

Line numbers: design and sync

Method: Use a read-only RichTextBox (rtbGutter) aligned with rtbEditor so scrolling and line wrapping appear consistent.

Key steps:

  • Keep rtbGutter read-only, same Font as rtbEditor, BackColor slightly different, BorderStyle = None.
  • Update gutter text whenever rtbEditor content or scroll position changes.

Core routine (conceptual VB .NET code):

vb

’ Call this on Form Load and whenever text or layout changes Private Sub UpdateLineNumbers()Dim lines As Integer = rtbEditor.Lines.Length

Dim sb As New System.Text.StringBuilder() For i As Integer = 1 To lines     sb.AppendLine(i.ToString()) Next rtbGutter.Text = sb.ToString() 

End Sub

Sync scrolling:

  • Handle rtbEditor.VScroll (no built-in event; use Win32 message or a timer) or rtbEditor.SelectionChanged to align the gutter’s first visible line.
  • Simpler approach: set rtbGutter.SelectionStart = rtbEditor.GetCharIndexFromPosition(New Point(0,0)) and call rtbGutter.ScrollToCaret() to match vertical position.

Example helper to scroll gutter (simplified):

vb

Private Sub SyncGutterScroll() Try

    Dim index As Integer = rtbEditor.GetCharIndexFromPosition(New Point(0, 0))     rtbGutter.SelectionStart = index     rtbGutter.ScrollToCaret() Catch ex As Exception     ' ignore End Try 

End Sub

Call UpdateLineNumbers() and SyncGutterScroll() from:

  • rtbEditor.TextChanged
  • rtbEditor.SelectionChanged
  • Form Resize

Performance tip: For large documents, avoid rebuilding the entire gutter on every keystroke. Use a short debounce timer (e.g., 100–200 ms) to batch updates.

Syntax highlighting: keyword-based approach

We’ll implement a fast, simple highlighter that colors VB .NET keywords and comments. This is not a full lexer but works well for small-to-medium files.

Design decisions:

  • Use RichTextBox’s selection-based formatting (fast enough for moderate sizes).
  • Preserve user selection and scroll position while applying formatting.
  • Use Regex to locate tokens: keywords, comments, strings.

Example keywords list (partial):

vb

Dim keywords As String() = {“Module”,“Sub”,“Function”,“Dim”,“As”,“If”,“Then”,“Else”,“End”,“For”,“Next”,“While”,“Return”,“Public”,“Private”,“Class”,“New”}

Highlighting routine (conceptual):

vb

Private Sub HighlightSyntax() ‘ Remember selection and scroll

Dim selStart = rtbEditor.SelectionStart Dim selLength = rtbEditor.SelectionLength Dim viewportIndex = rtbEditor.GetCharIndexFromPosition(New Point(1,1)) ' Disable redrawing for smoother visual update SendMessage(rtbEditor.Handle, WM_SETREDRAW, False, 0) ' Reset all text color to default rtbEditor.SelectAll() rtbEditor.SelectionColor = Color.Black ' Highlight comments (single-line starting with ') Dim commentPattern As String = "'.*$" For Each m As Match In Regex.Matches(rtbEditor.Text, commentPattern, RegexOptions.Multiline)     rtbEditor.Select(m.Index, m.Length)     rtbEditor.SelectionColor = Color.Green Next ' Highlight strings Dim stringPattern As String = """([^""]|"""")*""" For Each m As Match In Regex.Matches(rtbEditor.Text, stringPattern)     rtbEditor.Select(m.Index, m.Length)     rtbEditor.SelectionColor = Color.Brown Next ' Highlight keywords (word boundaries) For Each kw As String In keywords     Dim pattern As String = "" & Regex.Escape(kw) & ""     For Each m As Match In Regex.Matches(rtbEditor.Text, pattern, RegexOptions.IgnoreCase)         rtbEditor.Select(m.Index, m.Length)         rtbEditor.SelectionColor = Color.Blue     Next Next ' Restore selection and redraw rtbEditor.Select(selStart, selLength) SendMessage(rtbEditor.Handle, WM_SETREDRAW, True, 0) rtbEditor.Invalidate() ' Restore viewport rtbEditor.SelectionStart = viewportIndex rtbEditor.ScrollToCaret() 

End Sub

Notes:

  • WMSETREDRAW is used to prevent flicker during formatting. Import via:

vb

_ Private Shared Function SendMessage(hWnd As IntPtr, wMsg As Integer, wParam As Boolean, lParam As Integer) As Integer End Function Private Const WM_SETREDRAW As Integer = 11
  • Preserve user selection so typing isn’t disrupted.

Performance strategies:

  • Highlight only visible text range instead of entire document for large files. Use GetCharIndexFromPosition and measure visible lines.
  • Use a background worker or Task to compute token positions, then marshal formatting back to UI thread.
  • Cache regex matches when possible; re-run only on changed lines.

Handling editing and caret movement

  • Trigger highlighting on TextChanged with debounce, and minor updates on KeyUp for quick feedback.
  • Update line numbers and gutter sync on the same events.
  • For multi-threaded highlighting, ensure all RichTextBox updates run on the UI thread (Invoke/BeginInvoke).

Optional enhancements

  • Add brace matching (highlight matching parentheses).
  • Implement auto-indentation on Enter key.
  • Add customizable themes (colors, font) via settings.
  • Use a third-party text editor control (e.g., ScintillaNET) for robust editing features if you need high performance and full language support.

Example wiring (events)

  • rtbEditor.TextChanged -> Start debounce timer -> HighlightSyntax + UpdateLineNumbers + SyncGutterScroll
  • rtbEditor.SelectionChanged -> SyncGutterScroll
  • Form.Resize -> UpdateLineNumbers + SyncGutterScroll

Final notes

This approach gives a lightweight VB .NET Notepad with basic syntax highlighting and line numbers using built-in controls. For production-grade editors with large files and advanced language features, prefer specialized controls like ScintillaNET or AvalonEdit (WPF) which provide built-in lexing, folding, and much better performance.

If you want, I can provide a complete sample project (full VB .NET code files) implementing the routines above.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *