This guide is for developers who already have a working application built on ReoGrid V3 (the open-source MIT release) and want to upgrade to ReoGrid V4 (the commercial release).
V3 is still maintained as open source. V4 is a separate commercial product line with significantly more features. See What’s New in V4 for a feature overview.
TL;DR
- A drop-in DLL replacement will not compile. V4 changed several public class and interface names, removed some exception types, and reorganized a few areas.
- There is no
[Obsolete]compatibility shim. V4 is a clean break — old names are removed, not deprecated. - The breaking changes are mechanical. Most projects can be migrated with find-and-replace plus a handful of structural fixes. The core API surface (
Workbook,Worksheet,Cell,RangePosition,CellPosition,WorksheetRangeStyle, etc.) is unchanged. - Semantic changes are minor and Excel-aligned. Some behaviors changed to match Excel (formulas move with sorted rows, division-by-zero returns
#DIV/0!, etc.). Review section 2 below. - Distribution. V4 is currently delivered as DLLs through the customer portal after purchase. (NuGet packages will be released later.) The root namespace
unvell.ReoGridand the assembly name are unchanged, so swapping the DLL reference is the only build-configuration change required. V4 targetsnet48andnet8.0-windows.
0. Before you start: reference the right target framework
The V4 package ships two builds of unvell.ReoGrid.dll — one under a net48 folder and one under a net8.0-windows folder. Reference the one that matches your project’s target framework.
Mixing them produces a flood of errors that look like API breakage but aren’t:
Import of type 'Color' from assembly or module 'System.Drawing.Primitives.dll' failed.
Import of type 'Encoding' from assembly or module 'System.Runtime.dll' failed.
Import of type 'Stream' from assembly or module 'System.Runtime.dll' failed.
These are the classic symptom of a net48 project referencing the net8.0-windows build (or vice versa). The net8.0-windows DLL has type-forwards into facade assemblies (System.Runtime.dll, System.Drawing.Primitives.dll) that don’t exist on .NET Framework 4.8 in the same form. Once you switch to the matching build, dozens of these errors disappear at once — leaving only the real API differences listed below.
VB.NET projects: the same rule applies.
BC30005(“Reference required to assembly … containing the type …”) andBC30456after a V4 upgrade are almost always this mismatch, not a missing member. Fix the reference first, then re-build and triage what’s left.
1. Compile-error categories
These are the breaking changes you will hit when you first build against V4. Each one is mechanical to fix.
A. Action base class renamed
BaseWorksheetAction is now WorksheetAction.
- public class MyAction : BaseWorksheetAction
+ public class MyAction : WorksheetAction
- void RunAction(BaseWorksheetAction action) { sheet.DoAction(action); }
+ void RunAction(WorksheetAction action) { sheet.DoAction(action); }
This affects every custom undoable action you’ve written, plus any code that holds references to actions by base type. Worksheet.DoAction is also now public in V4 (was internal in V3), so external code can invoke actions directly.
B. Outline types renamed
The outline (row/column grouping) base class and interface were renamed to drop the ReoGrid prefix.
| V3 | V4 |
|---|---|
ReoGridOutline (abstract class) | BaseOutline |
IReoGridOutline (interface) | IOutline |
- IReoGridOutline g = sheet.GetOutline(RowOrColumn.Row, 0);
+ IOutline g = sheet.GetOutline(RowOrColumn.Row, 0);
The concrete RowOutline and ColumnOutline types still exist with the same names; only the base/interface types changed.
C. Header type renamed
ReoGridHeader is now WorksheetHeader.
- ReoGridHeader h = sheet.RowHeaders[0];
+ WorksheetHeader h = sheet.RowHeaders[0];
RowHeader and ColumnHeader still exist; they now inherit from WorksheetHeader instead of ReoGridHeader.
D. DropdownListCell hierarchy changed
DropdownListCell now extends a new intermediate class DropdownListBaseCell.
V3: CellBody → DropdownCell → DropdownListCell
V4: CellBody → DropdownCell → DropdownListBaseCell → DropdownListCell
If your code calls DropdownListCell directly, no change is required. If you have a custom subclass that extended DropdownListCell and overrode protected members, the inheritance chain has shifted — re-check your overrides. The new sibling class ComboListCell is also available and supports auto-completion.
E. Formula exception classes removed
V4 no longer throws (or exposes) the per-error formula exception classes. These types are gone:
FormulaEvalutionExceptionFormulaNoNameExceptionFormulaParameterMismatchExceptionFormulaTypeMismatchException
Any catch block referencing them will fail to compile. In V4, formula evaluation errors surface through:
Cell.FormulaStatus— aFormulaStatusenum value (e.g.InvalidName,InvalidValue)- The cell’s display value (
#NAME?,#DIV/0!,#VALUE!, etc., matching Excel)
Replace exception-based error handling with status checks:
- try { sheet.Recalculate(); }
- catch (FormulaNoNameException) { /* ... */ }
+ sheet.Recalculate();
+ if (sheet.Cells["A1"].FormulaStatus == FormulaStatus.InvalidName) { /* ... */ }
The general FormulaParseException (parse-time) and the new FormulaSyntaxErrorException / FormulaLiteralTooLongException classes are still public and may be caught.
F. IsValidAddress renamed (v4.3.0)
For clarity, the V3 method that checked address-string format was renamed:
- if (RangePosition.IsValidAddress(addr)) { ... }
+ if (RangePosition.IsValidAddressFormat(addr)) { ... }
Worksheet.IsValidAddress(string) was added in V4 with stricter semantics — it both validates the format and verifies the address is in range. New helpers Worksheet.IsValidCellAddress(string, out CellPosition) and Worksheet.IsValidRangeAddress(string, out RangePosition) combine validation with safe parsing. Prefer these in new code.
G. ConditionalStyleApplyCells removed (v4.4)
The ConditionalStyleApplyCells property and ConditionalStyleApplyCellCollection class were removed.
To check whether a cell has a conditional style applied:
// Lightweight per-cell check
bool has = sheet.Cells["A1"].HasConditionalStyles;
// Or via worksheet
bool has = sheet.HasConditionalStyle(0, 0);
bool has = sheet.HasConditionalStyle(new CellPosition("A1"));
H. AutoFitColumnWidth / AutoFitRowHeight renamed and signature changed
The single-row / single-column auto-fit methods on Worksheet were renamed to a plural form that takes a range:
| V3 | V4 |
|---|---|
worksheet.AutoFitColumnWidth(int col, bool byAction = false) | worksheet.AutoFitColumnsWidth(int startCol, int colCount, int padding = 0) |
worksheet.AutoFitRowHeight(int row, bool byAction = false) | worksheet.AutoFitRowsHeight(int startRow, int rowCount, bool byAction = false) |
- worksheet.AutoFitColumnWidth(2);
+ worksheet.AutoFitColumnsWidth(2, 1);
- worksheet.AutoFitRowHeight(0, byAction: true);
+ worksheet.AutoFitRowsHeight(0, 1, byAction: true);
The AutoFitColumnWidth() / AutoFitRowHeight() methods on individual ColumnHeader / RowHeader instances still exist (marked [Obsolete]) but forward to the new plural worksheet methods. For better performance on multiple columns/rows, call the worksheet API directly with a range rather than looping over single headers.
I. DropdownListCell.Items removed
V3 exposed a mutable DropdownListCell.Items property (a DropdownItemsCollection) that you could .Add() into after construction. V4 replaces this with an immutable CandidateSource (an IStringValueListSource) supplied at construction time.
- var dropdown = new DropdownListCell();
- dropdown.Items.Add("USD");
- dropdown.Items.Add("JPY");
- dropdown.Items.Add("EUR");
+ var dropdown = new DropdownListCell("USD", "JPY", "EUR");
+ // or: new DropdownListCell(new[] { "USD", "JPY", "EUR" });
To bind to a range of cells instead of a static list:
var listRange = sheet.Ranges["G1:G3000"];
var dropdown = new DropdownListCell(listRange);
To read the current candidates: dropdown.CandidateSource.Items (read-only IEnumerable<string>).
Need to mutate items after construction? Hold on to the underlying IEnumerable<string> reference yourself. StringListSource stores the reference you pass in — it does not copy — and the dropdown re-reads it every time the popup opens. So mutating the original list is the V4 equivalent of V3’s dropdown.Items.Add(...):
var list = new List<string> { "Item 1", "Item 2", "Item 3" };
var dropdown = new DropdownListCell(list);
sheet.Cells["F2"].Body = dropdown;
list.Add("Item 4"); // ✓ visible next time the dropdown opens
list.AddRange(new[] { "Item 5", "Item 6" }); // ✓
list.Clear(); // ✓
list = new List<string>(); // ✗ new instance — old reference still held
For more complex scenarios (filtering, async loading, etc.) implement a custom IStringValueListSource whose Items getter returns your live collection.
J. Long-deprecated V3 types are gone
If your project hasn’t been rebuilt in a few years you may also see errors referencing names that were already [Obsolete] in late-V3 and have now been removed in V4. The most common one:
Type 'unvell.ReoGrid.ReoGridCell' is not defined
ReoGridCell was renamed to Cell in V3 around 2018; the obsolete shim class was removed from V3 itself in April 2021 (V3 v1.7) and is not present in V4 either. The fix is the same for both:
- unvell.ReoGrid.ReoGridCell cell = sheet.GetCell(0, 0);
+ unvell.ReoGrid.Cell cell = sheet.GetCell(0, 0);
Other obsolete-then-removed names from the same V3 cleanup that may appear: IsHidden (use !IsVisible), and various ReoGrid-prefixed type aliases. Treat any “type is not defined” error for an old-looking name as a candidate for this category.
K. VB.NET: Color cannot be implicitly converted to SolidColor
This isn’t strictly a V3→V4 break — it affects V3 too — but VB.NET users often discover it during the V4 upgrade because they hit it across many lines at once.
Value of type 'Color' cannot be converted to 'SolidColor'.
ReoGrid defines an implicit conversion operator from System.Drawing.Color to SolidColor (in the WinForms build). C# uses it automatically; VB.NET with Option Strict On does not — VB treats C# user-defined implicit operators as narrowing and requires an explicit cast.
' Won't compile under Option Strict On:
sheet.Cells("A1").Style.BackColor = Color.Red
' Fixes — pick one:
sheet.Cells("A1").Style.BackColor = SolidColor.Red
sheet.Cells("A1").Style.BackColor = SolidColor.FromArgb(255, 0, 0)
sheet.Cells("A1").Style.BackColor = CType(Color.Red, SolidColor)
Prefer SolidColor.Red (and other named SolidColor constants) in new VB.NET code. WPF build: the System.Drawing.Color → SolidColor operator doesn’t exist at all — use SolidColor directly or convert from System.Windows.Media.Color.
2. Behavior changes (compiles, but behaves differently)
These compile silently but may change how your application behaves. Review them if your tests fail unexpectedly.
Sort moves formulas with rows
V3 sorted only the data values; formula cells stayed in place. V4 moves formulas along with their row, matching Excel. If your application relied on formulas staying anchored after a sort, you’ll need to re-anchor with absolute references ($A$1) or remove the formulas before sorting.
Conditional styles evaluated at render time
V3 re-evaluated conditional styles on every cell edit. V4 marks them dirty and evaluates them once per render cycle. This is much faster on large sheets, but if you read a cell’s effective style immediately after assigning data and before the next paint, the conditional style may not be reflected yet. For non-render code paths, query HasConditionalStyles and re-evaluate explicitly if needed.
Excel-compatible formula parsing
V4 brings the formula parser closer to Excel:
- Unary plus.
=+D25-F8-F14now parses correctly (V3 raised an error). - Quoted sheet names with parentheses or whitespace.
'BS(USD)'!B3,'My Sheet'!A1are now valid. 0evaluates as FALSE.IF(0, x, y)returnsy. Any non-zero number is TRUE. Code that relied on0 ≠ FALSEwill now branch differently.- Division by zero.
=A1/0returns#DIV/0!andCell.FormulaStatusbecomesFormulaStatus.InvalidValueinstead ofNormal. - String multiplication coercion.
="10"*2now returns20(V3 raised an error). - VLOOKUP / HLOOKUP / MATCH / XMATCH / XLOOKUP are implemented; approximate matching requires sorted input as in Excel.
Sheet-tab rendering, scroll behavior, font lookup
If you have UI snapshots or pixel-level visual tests, expect minor differences in scrollbar limits, font fallback, sheet-tab drawing, and zoom-time text scaling. These are rendering improvements; verify rather than assume regression.
Floating-point precision
V4 introduces WorksheetOptions.FormulaCalculationPrecision. The default is NoPrecisionCorrection (V3-compatible — fastest, may show 3.00000000000004). Switch to LowPrecision for Excel-like display:
sheet.Options.FormulaCalculationPrecision = FormulaCalculationPrecision.LowPrecision;
3. New APIs you’ll likely want to adopt
Once your code compiles and your existing tests pass, these are the V4 features most worth integrating. They are additive — none of them are required for migration.
Lazy loading for million-row datasets
worksheet.SetRows(1_000_000);
worksheet.AddDataSource(
new RangePosition(0, 0, 1_000_000, 10),
new MyDataSource(logs),
DataSourceLoadMode.LazyLoading);
V3’s IDataSource<T> was for charts only. V4 introduces a separate unvell.ReoGrid.Data.IDataSource<T> for binding rows of data to a cell range, with optional lazy streaming.
Multi-row column headers
var ext = worksheet.ExtensionColumnHeader;
ext.SetRowCount(3);
ext.MergeCells(0, 1, 2, 1);
ext[0, 1].Text = "Category";
Conditional styles
using unvell.ReoGrid.ConditionalStyle;
var rule = new Rule("THIS > 1000", "A1:Z30",
new WorksheetRangeStyle {
Flag = PlainStyleFlag.TextColor,
TextColor = SolidColor.Yellow,
});
sheet.ConditionalStyles.Add(rule);
THIS is a reserved keyword referencing the current cell value.
Conditional filters
using unvell.ReoGrid.Data.ConditionFilter;
var filter = new ConditionalDataFilter();
filter.Conditions.Add(new FilterCondition(2, ConditionOperator.NotEquals, "USD"));
sheet.DoFilter("A1:G30", filter);
Three-level cell locking
V4 adds Cell.IsLocked (type CellLock enum: Locked, Unlocked, Inherit). V3 had no per-cell lock model.
sheet.IsLocked = true;
sheet.Cells["C5"].IsLocked = CellLock.Unlocked;
Note: the enum value is
Unlocked(one capital). Some older snippets showUnLocked— that’s a typo.
Excel-compatible custom number formats
cell.DataFormat = CellDataFormatFlag.Number;
cell.DataFormatArgs = "#,##0;[Red]-#,##0";
DropdownListCell with a cell-range source
var listRange = sheet1.Ranges["G1:G3000"];
var dropdown = new DropdownListCell(listRange);
sheet1.Cells["A1"].Body = dropdown;
Workbook-wide highlighted text search
using unvell.ReoGrid.TextSearch;
var session = new HighlightTextSearchSession(Workbook, keyword, Workbook.CurrentWorksheet);
session.Search();
session.MarkAllResultHighlight(SolidColor.Goldenrod);
session.NextMatch();
Outline collapse/expand all & button placement
sheet.OutlineButtonLocation = OutlineButtonLocation.Top;
var group = sheet.GetOutlineGroup(RowOrColumn.Row, 0);
group.CollapseAll();
group.ExpandAll();
WinAppDriver UI automation
ReoGridControl.EnableUIAutomation = true;
See What’s New in V4 for the full feature catalog and Release Notes for per-version changes.
4. Migration checklist
- Replace your V3 DLL reference with the V4 DLL (delivered via the customer portal)
- Confirm your project targets
net48ornet8.0-windows, and that the referenced V4 DLL is from the matching folder (section 0) - Build — fix the rename errors from section 1 (A–K)
- Replace formula
catchblocks withCell.FormulaStatuschecks (section 1-E) - Run your existing test suite — investigate any sort-order, formula, or division-by-zero differences (section 2)
- (Optional) Adopt the new APIs in section 3 where they fit your application
5. Licensing
V4 is a commercial licensed product. Editions:
| V4 Professional | V4 Enterprise | |
|---|---|---|
| Devices | Up to 3 | Unlimited |
| Technical support | 1 month | 3 months |
| Pricing | See pricing | See pricing |
V3 remains available as MIT-licensed open source on GitHub.
6. Getting help
If you hit a migration issue not covered here — especially around custom cell types, custom actions, or large data binding flows — please contact support. We can advise on the best V4 equivalents for your V3 patterns.