This is a step-by-step guide for migrating an application built with ReoGrid V4 to V5 (ReoGrid One).
There is no automated migration tool. V5 is a complete redesign with no backward compatibility, and your code will need to be rewritten. This page describes the order in which to do that work with the least amount of rework.
For the full list of API changes, see Differences from V4. This page focuses on the process.
1. First, decide whether to migrate
Migration is not mandatory. V4 continues as the 4.x line, and your existing applications will not stop working. License keys are shared as well.
Migration is worth considering if any of the following applies.
| Situation | What V5 solves |
|---|---|
| Memory or speed becomes a problem beyond tens of thousands of rows | About 16–23 B per cell (V4: about 150–200 B); work is proportional to the visible range |
| You want to work with sheets on a server or in batch processing | Workbook / Worksheet are UI-independent; everything works without a screen |
| You want to run on Linux / macOS | Covered by the Avalonia and headless editions |
| You want to export PDF directly | One line with PdfExporter; Japanese fonts embedded |
| You want to exchange files with the Web edition | reogrid-json is the shared format |
Conversely, do not migrate yet if either of the following applies.
- You cannot move to .NET 10. V5 supports .NET 10 and later only (net48 / net8 are not supported)
- You depend on one of the “features not yet in V5” listed below
Estimating the effort
Most of the rewriting is mechanical. As a rough guide, an application centered on cell operations, formatting and I/O can be migrated by rewriting a few hundred lines. What takes time is code that depends on V4’s fine-grained events, and working around the feature gaps described below.
2. Pre-migration check — does V5 have the features you use?
Before you start, go through the following list. If anything applies, that will be your biggest challenge.
Features not yet in V5
| Feature | Typical V4 usage | Options for now |
|---|---|---|
| Charts | The chart types under Chart/ | Pair with a separate charting library / stay on V4 |
| Cell comments | Comment | Substitute cell types or tooltips |
| Shapes and text boxes | Drawing/ | Images still work in V5 |
| Data binding | IDataSource / ArrayDataSource | Write values in a loop |
| Input validation | IValidator / CellValidation | Validate yourself after input |
| Text search | TextSearch/ | Implement it yourself by scanning the used range |
| ReoScript | RunScript | Removed. It will not return |
| Some cell types | DatePicker / RadioButton / NumberInput / image-based types | Can be implemented as custom cell types |
Charts, comments, shapes, data binding, input validation and text search are not available in V5.0. There is no committed schedule for them — they will be considered based on demand (see the roadmap section of the release notes). Because the license is version-independent (one license covers V4 and V5), you can simply keep using V4 for as long as you need those features.
File formats
| V4 format | V5 |
|---|---|
RGF (.rgf) | Cannot be read. Migrate via XLSX (next section) |
| XLSX | Reads as-is |
BinaryFormatter | Removed |
Licensing
Keys already issued for V4 work as-is with V5. No reissue request is needed. A single key covers WinForms, WPF, Avalonia and headless (Applying a license key).
3. Move your data
V5 cannot read RGF files. Convert them to XLSX while V4 is still in place.
① Open the .rgf file in your V4 application (or the V4 Editor)
② Save it as XLSX
③ Read it in V5 with XlsxReader.Read()
Do this before uninstalling V4. Only V4 can perform the conversion.
If you need to keep reading and writing RGF files, consider keeping that part on V4 and leaving it out of the migration.
4. Replace the project references
Change your .csproj as follows.
<PropertyGroup>
<!-- 変更前: <TargetFramework>net48</TargetFramework> -->
<TargetFramework>net10.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <!-- WPF なら <UseWPF>true</UseWPF> -->
</PropertyGroup>
<ItemGroup>
<!-- 変更前: <PackageReference Include="unvell.ReoGrid4" Version="4.*" /> -->
<PackageReference Include="unvell.ReoGrid.One" Version="5.0.0-alpha" />
</ItemGroup>
| V4 package | V5 |
|---|---|
unvell.ReoGrid4 | unvell.ReoGrid.One |
unvell.ReoGrid4.Wpf | unvell.ReoGrid.One.Wpf |
| (none) | unvell.ReoGrid.One.Avalonia, unvell.ReoGrid.One.Core |
The V5 packages include XLSX / PDF I/O. No additional references are needed.
5. Rewrite the using directives
At this point you will get a flood of compile errors — that is expected. The following mapping resolves most of them.
| V4 | V5 |
|---|---|
using unvell.ReoGrid; | using unvell.ReoGrid.Core; |
| (WinForms control) | using unvell.ReoGrid.WinForms; |
| (WPF control) | using unvell.ReoGrid.Wpf; |
using unvell.ReoGrid.Graphics; | using unvell.ReoGrid.Core.Style; |
using unvell.ReoGrid.CellTypes; | using unvell.ReoGrid.Core.CellTypes; |
using unvell.ReoGrid.IO; | using unvell.ReoGrid.IO.Excel; / unvell.ReoGrid.Core.IO; |
using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.CellTypes;
using unvell.ReoGrid.Core.Style;
The full list is in Installation.
6. Rewrite the code
Work in the following order. Fixing the parts with the fewest dependencies first reduces rework.
① Creating workbooks
// V4: var sheet = reoGridControl.CurrentWorksheet;
// V4: var ws2 = reoGridControl.Worksheets.Create("Sheet2");
// V4: var wb = ReoGridControl.CreateMemoryWorkbook(); // 画面なしの場合
var wb = new Workbook();
var ws = wb.AddWorksheet("Sheet1");
control.LoadWorkbook(wb); // UI に載せるときだけ
var active = control.ActiveWorksheet; // V4: control.CurrentWorksheet
CreateMemoryWorkbook() for screenless use is no longer needed. In V5, new Workbook()
has no dependency on a control to begin with.
② Cell values — where most of the rewriting happens
// V4: sheet["A1"] = 10;
// V4: sheet[4, 0] = "text";
ws.SetNumber(0, 0, 10);
ws.SetText(4, 0, "text");
// V4: var s = sheet.GetCellData<string>("A2");
// V4: object v = sheet["A1"];
object? v = ws.GetObjectValue(0, 0);
string shown = ws.GetDisplayText(0, 0);
The indexer behaves differently (watch out)
// V4 の ws[0, 0] は object の get/set だった。
// V5 の ws[0, 0] は CellCursor を返す get 専用 —— 代入するとコンパイルエラーになる。
//
// ws[0, 0] = 10; // CS0200: 代入できない
//
// カーソル経由か、型付きメソッドを使う。
ws[0, 0].SetNumber(10);
ws.SetNumber(0, 0, 10);
Assignments become compile errors, so you will notice them — reads are the ones to
watch. var v = ws[0, 0]; is a value in V4 but a CellCursor in V5. Check the type
wherever the result is received with var.
There is no sugar equivalent to V4’s bulk fill from an object[]
(sheet["B5"] = new object[] {...}). Write a loop instead.
③ Formulas
// V4: sheet["A3"] = "=SUM(A1:A2)"; // 値として代入していた
ws.SetFormula(2, 0, "SUM(A1:A2)"); // 先頭の '=' は付けない
// V4: string f = sheet.GetCellFormula("A3"); // "=SUM(A1:A2)" が返る
string? f = ws.GetFormula(2, 0); // "SUM(A1:A2)"('=' なし)
The leading = is the easiest thing to get wrong. When handling strings typed by the
user (where you want the leading = to decide whether it is a formula), use the control’s
SetActiveCellInput(text). Like V4, it accepts strings with the = prefix.
④ Styles
// V4: worksheet.SetRangeStyles(range, new WorksheetRangeStyle {
// V4: Flag = PlainStyleFlag.BackColor | PlainStyleFlag.FontStyleBold,
// V4: BackColor = Color.Yellow, Bold = true });
// V5: Flag は不要(null が「指定しない」)。色は uint ARGB。
for (int r = range.Row; r <= range.EndRow; r++)
for (int c = range.Col; c <= range.EndCol; c++)
ws.SetCellStyle(r, c, (ws.GetCellStyle(r, c) ?? StyleRecord.Default)
with { BackgroundColor = 0xFFFFFF00u, Bold = true });
PlainStyleFlag has been removed. A StyleRecord property being null is itself what
means “not specified”. Colors are uint ARGB values, not System.Drawing.Color
(opaque yellow is 0xFFFFFF00u).
There is no method equivalent to the range-wide SetRangeStyles. However, when you
want to affect an entire column or row, do not turn it into a loop.
// 列・行の全体に効かせたい場合は、セルを回さず既定スタイルへ。
// V4 の SetRangeStyles(列全体) を素直に移すとセル数ぶん実体化する。
ws.SetColumnStyle(0, new StyleRecord { TextAlign = HAlign.Right });
ws.SetRowStyle(0, new StyleRecord { Bold = true });
This is where migration makes the biggest performance difference. Translating V4 code straight into loops throws away the memory efficiency that is V5’s advantage (Style inheritance).
For the UI selection there are helpers such as control.SetSelectionBackColor(...),
which detect whole-row and whole-column selections automatically.
⑤ Borders
// V4: worksheet.SetRangeBorders(range, BorderPositions.Outside,
// V4: RangeBorderStyle.BlackSolid);
ws.Borders.SetOutline(range, new BorderEdge(BorderLineStyle.Solid, 0xFF000000u, 1f));
The BorderPositions bit flags and presets have been removed. Borders inside a range
(the equivalent of InsideAll) are currently set in a loop (Borders).
⑥ Number formats
// V4: worksheet.SetRangeDataFormat(range, CellDataFormatFlag.Number,
// V4: new NumberDataFormatter.NumberFormatArgs {
// V4: DecimalPlaces = 2, UseSeparator = true });
ws.SetNumberFormat(range, "#,##0.00");
CellDataFormatFlag and the *FormatArgs types are gone entirely, replaced by the same
format codes as Excel. V4’s NumberNegativeStyle.RedBrackets is written as
#,##0;[Red](#,##0) (Number formats).
⑦ Structural operations
// V4: worksheet.SetColumnsWidth(2, 1, 160);
ws.Columns.SetSize(2, 160);
// V4: worksheet.FreezeToCell(1, 1); // モデル側の状態だった
control.SetFreeze(1, 1); // V5 はビュー側
Freeze panes have moved to the view side. As a result, they are not persisted at the moment. You need to set them again each time after opening a file.
⑧ Cell types
// V4: worksheet[3, 1] = new CheckBoxCell();
// V4: var dd = new DropdownListCell("Apple", "Orange");
// V4: worksheet["C3"] = dd;
// V4: dd.SelectedItemChanged += ...;
ws.SetCellType(3, 1, CheckboxCellType.Instance);
ws.SetCellType(RangePosition.Parse("C3:C100"),
new DropdownCellType(["Apple", "Orange"]));
// 状態はセル値。イベントはコントロール側で受ける。
ws.SetBoolean(3, 1, true);
Instead of assigning an instance to each cell, you now assign a descriptor to a range.
Per-cell-type events (such as dd.SelectedItemChanged) have been removed; button clicks
are received through the control’s CellButtonClicked
(Cell type concepts).
⑨ Events
There is no simple substitution here. V4 had many events on Worksheet, but in V5
the model types have no events. The only events are the seven on the control layer.
| V4 event | V5 equivalent |
|---|---|
SelectionRangeChanged | control.SelectionChanged |
CellDataChanged | No equivalent — raise the notification from the code that changes the value |
BeforeCellEdit / AfterCellEdit | Track edit start and commit from your control operations |
CellMouseDown / CellMouseMove etc. | Receive what you need through control.ContextMenuRequested and CellButtonClicked |
BeforePaste | Wrap pre- and post-paste processing on the calling side |
If you were detecting cell changes to trigger other processing, you need to provide that notification path yourself. In most cases the code writing the values is your own, so adding a hook there is the shortest route.
⑩ File I/O
| V4 | V5 |
|---|---|
wb.Load(path) | XlsxReader.Read(path) |
wb.Save(path, FileFormat.Excel2007) | XlsxWriter.Write(wb, path) |
worksheet.SaveRGF(path) | Removed → ReoGridJsonIO.Write(wb) |
worksheet.ExportAsCSV(path) | CsvIO.Write(ws) |
| (via printing only) | PdfExporter.Export(wb, path) |
There is no automatic format detection through the FileFormat enum. Call the class for
each format directly.
Formulas are not re-evaluated right after loading an XLSX file. The cached values
saved by Excel are used. If you want to recompute yourself, call sheet.Recalculate()
explicitly (XLSX I/O).
7. Common compile errors and fixes
| Error | Cause | Fix |
|---|---|---|
CS0200 プロパティまたはインデクサに代入できません | ws[r, c] = value | ws.SetNumber(r, c, v) / ws[r, c].SetNumber(v) |
CS0246 型 WorksheetRangeStyle が見つかりません | Style type changed | StyleRecord |
CS0246 型 PlainStyleFlag が見つかりません | Removed | Safe to delete (null plays the same role) |
CS1503 Color から uint に変換できません | Color type | Use a uint in 0xAARRGGBB form |
CS0246 型 CellDataFormatFlag が見つかりません | Removed | SetNumberFormat(range, "format code") |
CS0117 BorderPositions に定義がありません | Removed | ws.Borders.SetOutline(...) / SetEdge(...) |
CS1061 CurrentWorksheet の定義がありません | Renamed | ActiveWorksheet |
CS1061 SelectionRange の定義がありません | Moved to the view | control.Selection |
CS1061 CellDataChanged の定義がありません | Removed | Provide your own notification path |
CS0246 型 FileFormat が見つかりません | Removed | XlsxWriter.Write(wb, path) |
Code that compiles but behaves differently
This is the easiest part of the migration to overlook.
| Symptom | Cause |
|---|---|
| Formulas are displayed as strings | Passing a leading = to SetFormula |
A value received with var is unusable | The indexer now returns a CellCursor |
| Slow startup, high memory usage | Formatting an entire column with a per-cell loop |
| Freeze panes are not saved | They are now view-side state (by design) |
| The selection is not saved | Same as above (by design) |
8. Verification
Things to check after migrating.
- Load existing XLSX files and confirm the display matches V4
- Open exported XLSX files in Excel and confirm nothing is broken
- Formula results match (check whether
Recalculate()is needed) - Number formats look the same (fractions, scientific notation and Japanese era dates are not supported)
- Display on high-DPI environments (
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2)) - Startup time and memory with large data (should have improved; if it got worse, suspect a formatting loop)
- The license key is accepted (no watermark is shown)
Migration checklist
□ Confirmed the project can move to .NET 10
□ Confirmed every feature you use exists in V5 (charts, comments, shapes, validation, search, ReoScript)
□ Converted RGF files to XLSX (while V4 is still installed)
□ Swapped the csproj TFM and packages
□ Rewrote the using directives
□ Moved cell reads/writes to the typed methods
□ Removed the leading '=' from formulas
□ Moved styles to StyleRecord (whole columns/rows to default styles)
□ Moved borders and number formats to the new APIs
□ Moved cell types to range assignment
□ Prepared alternative notification paths for event-driven code
□ ファイル入出力を形式ごとのクラスへ移した
□ 上記の動作確認を通した
Keeping parts on V4
You do not have to move everything at once. Because the V5 core has no UI dependency, you
can also leave your existing V4 application as it is and write only new batch or server
features against V5 (unvell.ReoGrid.One.Core).
The two can exchange data through XLSX.
Read next
- Differences from V4 — the API comparison at a glance
- Applying a license key
- Release notes — planned future work