V4 V5

ReoGrid One works from VB.NET as-is; there is no separate package. Here is what to know when translating the C# samples.

Setting up the project

Add the NuGet package to your .vbproj (Installation).

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net10.0-windows</TargetFramework>
    <UseWindowsForms>true</UseWindowsForms>
    <RootNamespace>MyApp</RootNamespace>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="unvell.ReoGrid.One" Version="5.0.0" />
  </ItemGroup>
</Project>

For WPF use unvell.ReoGrid.One.Wpf, for Avalonia unvell.ReoGrid.One.Avalonia, and for headless work unvell.ReoGrid.One.Core.

Option Strict On is fine. Every sample below has been checked to compile with it on.

Initializing (WinForms)

Imports System.Windows.Forms
Imports unvell.ReoGrid.Core
Imports unvell.ReoGrid.WinForms

Public Class MainForm
    Inherits Form

    Private WithEvents grid As ReoGridControl

    Public Sub New()
        Text = "ReoGrid One - VB.NET"
        Width = 1000
        Height = 700

        grid = New ReoGridControl() With {.Dock = DockStyle.Fill}
        Controls.Add(grid)
    End Sub

    Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' new ReoGridControl() starts out holding a single Sheet1
        Dim ws As Worksheet = grid.ActiveWorksheet

        ws.SetText(0, 0, "Item")
        ws.SetText(0, 1, "Unit price")
        ws.SetText(0, 2, "Qty")
        ws.SetText(0, 3, "Amount")

        ws.SetText(1, 0, "Notebook")
        ws.SetNumber(1, 1, 180)
        ws.SetNumber(1, 2, 12)
        ws.SetFormula(1, 3, "B2*C2")

        grid.SetFreeze(rows:=1, cols:=0)
    End Sub

    ' WithEvents + Handles is available for events
    Private Sub grid_SelectionChanged(sender As Object, e As EventArgs) _
            Handles grid.SelectionChanged
        Text = $"{grid.ActiveCell.Row},{grid.ActiveCell.Col}"
    End Sub
End Class

Declaring the field Private WithEvents is what enables Handles. Using the designer — add ReoGridControl to the toolbox and drop it on the form — works just as well.

For work with no UI (a batch job, a server), you do not need a control at all.

Imports unvell.ReoGrid.Core

Dim wb As New Workbook()
Dim ws = wb.AddWorksheet("Sheet1")
ws.SetText(0, 0, "Branch")

Translating the C# samples

The documentation’s samples are in C#. There are five differences.

1. Record with expressions

VB has no equivalent of C#‘s with. Use MergeOver.

' C#: ws.RootStyle = ws.RootStyle with { FontFamily = "Segoe UI", FontSize = 11f };
ws.RootStyle = ws.RootStyle.MergeOver(
    New StyleRecord With {.FontFamily = "Segoe UI", .FontSize = 11.0F})

MergeOver means “what you set wins, what you left out is kept”, which gives the same result as with (Style Inheritance).

To build one from scratch, an object initializer works directly. StyleRecord’s properties are init-only, but VB can still set them in an initializer.

ws.SetColumnStyle(1, New StyleRecord With {.TextAlign = HAlign.Right})

2. Collection expressions

C#‘s ["A", "B"] is an array literal in VB.

' C#: new DropdownCellType(["Not started", "In progress", "Done"], editable: false)
ws.SetCellType(1, 0, New DropdownCellType(
    New String() {"Not started", "In progress", "Done"}, editable:=False))

3. Named arguments

:= rather than :.

ws.Cell("C3").SetCellType(New ProgressCellType(max:=100))
Dim small = wb.AddWorksheet("Log", rows:=5000, cols:=32)

4. Lambdas

Sub() when nothing is returned, Function() when something is.

' recording an edit in the history
ws.RecordCell("Enter value", 0, 0, Sub() ws.SetNumber(0, 0, 100))

' visiting only the cells that exist
ws.ReadWindow(0, 0, 10, 10,
    Sub(row As Integer, col As Integer, v As CellValue, styleId As Integer)
        Console.WriteLine(v.AsNumber)
    End Sub)

' changing the selection's formatting (control side)
grid.MutateSelectionStyle(Function(st) st.MergeOver(New StyleRecord With {.Bold = True}))

To attach an event handler dynamically, use AddHandler.

AddHandler grid.CellButtonClicked,
    Sub(s, e) MessageBox.Show($"{e.Cell.Row},{e.Cell.Col}")

5. out arguments

In VB you declare a variable and pass it.

' C#: if (ws.TryGetUsedRange(out var used)) { ... }
Dim used As RangePosition = Nothing
If ws.TryGetUsedRange(used) Then
    Console.WriteLine(used.Rows)
End If

' C#: string text = ws.GetFormattedText(0, 0, out uint? color);
Dim color As UInteger? = Nothing
Dim text = ws.GetFormattedText(0, 0, color)

Indexers

C#‘s wb[0] / ws[2, 1] become parentheses in VB.

Dim first As Worksheet = wb(0)
Dim named As Worksheet = wb("Sheet1")     ' Nothing when not found
Dim cur As CellCursor = ws(2, 1)

The imports you need

NamespaceMain types
unvell.ReoGrid.CoreWorkbook Worksheet RangePosition CellPosition
unvell.ReoGrid.Core.DataCellValue
unvell.ReoGrid.Core.StyleStyleRecord HAlign VAlign NumberFormatter
unvell.ReoGrid.Core.CellTypesCheckboxCellType and the rest
unvell.ReoGrid.Core.IOReoGridJsonIO CsvIO
unvell.ReoGrid.Core.PrintingPrintSettings
unvell.ReoGrid.IO.ExcelXlsxReader XlsxWriter
unvell.ReoGrid.IO.PdfPdfExporter
unvell.ReoGrid.WinForms / .Wpf / .AvaloniaReoGridControl

Dates

VB’s Date is the same type as DateTime, so pass it straight through.

ws.SetObjectValue(3, 0, New Date(2026, 8, 19))
ws.SetNumberFormat(3, 0, "yyyy/mm/dd")

' converting back from the serial when reading
Dim d As Date = Date.FromOADate(ws.GetValue(3, 0).AsNumber)
Was this article helpful?