Migrating from Classic Edition
This guide helps you convert an existing List & Label "Classic" application to use the Cross Platform (CP) edition.
Understanding the migration
Migrating from Classic to Cross Platform is not a simple drop-in replacement. The two editions differ in architecture, feature set, and API surface.
What changes in Cross Platform
- Project file format: Custom formats (.lst, .lbl, etc.) → JSON
- Rendering engine: GDI+ (Windows-only) → SkiaSharp (cross-platform)
- Interactive components: Preview dialogs, designer controls → Removed
- Feature set: Some advanced features → Not yet supported
Migration workflow
This guide walks you through:
- Converting project files to JSON
- Updating assembly/NuGet references
- Removing unsupported options
- Adjusting export calls
- Testing and validation
Note
The classes required for conversion are contained in a separate NuGet package, combit.ListLabel31.ProjectConverter. Add this package to enable conversions.
If you're creating a standalone converter app (not integrating into your existing application), also reference either combit.ListLabel31 or combit.ListLabel31.Enterprise, depending on which your classic app uses.
Convert your project files
First, convert all project files to the new JSON-based format. If you're already working with a repository, the easiest option is to use a SynchronizedRepository.
For file-based reports, you can instead use the ProjectConverter class.
The following C# example demonstrates this approach - just adjust the paths as needed.
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using combit.Reporting.ProjectConverter;
class Program
{
static void Main()
{
// Path to your existing LL project files
string sourcePath = @"C:\MyApp\ProjectFiles";
// Path where converted JSON files will be saved
string destinationPath = @"C:\MyApp\ConvertedProjectFiles";
// File extensions to convert - adjust as needed
string[] fileEndings = { ".lsr", ".lst", ".lbl", ".srt" };
// Create a new ProjectConverter
ProjectConverter projectConverter = new();
// Find all matching files in the source directory (including subfolders)
var files = Directory
.EnumerateFiles(sourcePath, "*.*", SearchOption.AllDirectories)
.Where(file => fileEndings
.Any(ext => file.EndsWith(ext, StringComparison.OrdinalIgnoreCase)));
var projectConversionOptions = new projectConversionOptions
{
DestinationDirectory = destinationPath,
OutputExistsBehavior = OutputExistsBehavior.Overwrite,
WriteIndented = true,
ConvertReferencedProjects = false,
ImportData = "ProjectConverter"
};
// Convert all files in one batch
projectConverter.ConvertProjectsAndWriteToFile(files, projectConversionOptions);
Debug.WriteLine("Finished");
}
}
Note
- When using expression-based formulas for object coordinates, widths, heights, etc., always wrap numeric values in
UnitFromSCM. SCM units are 1/1000 mm. For example, to set a field's width to the table width minus 2 cm, useTableWidth()-UnitFromSCM(20000)as formula (20000 SCM = 20 mm = 2 cm). - Always back up your original project files before running the converter.
- The converter supports
ConvertReferencedProjects, but by default you may disable it if you don't have any references. - There are a number of additional conversion methods that also enable conversions on repositories.
Update your assembly or NuGet reference
In your project file (.csproj), replace the classic LL assembly reference or NuGet package with the Cross Platform variant.
<!-- Remove or comment out the old package -->
<!-- <PackageReference Include="combit.ListLabel31" Version="31.*.*" /> -->
<!-- Add the Cross Platform package -->
<PackageReference Include="combit.ListLabel31.CrossPlatform" Version="31.*.*" />
If you referenced the DLL directly:
<!-- Old reference -->
<!-- <Reference Include="combit.ListLabel31"> -->
<!-- <HintPath>..\libs\combit.ListLabel31.dll</HintPath> -->
<!-- </Reference> -->
<!-- New CP reference -->
<Reference Include="combit.ListLabel31.CrossPlatform">
<HintPath>..\libs\combit.ListLabel31.CrossPlatform.dll</HintPath>
</Reference>
Remove unsupported options
List & Label Cross Platform does not support many of the legacy settings from the classic API. Remove or comment out any code that sets unsupported properties on ListLabel.
Example: Removing unsupported code
Before (Classic Edition):
listLabel.AutoShowPrintOptions = true;
listLabel.AutoShowSelectFile = true;
listLabel.AutoBoxType = LlAutoBoxType.None;
After (Cross Platform):
// These properties do not exist in Cross Platform - remove them
// Use ExportConfiguration instead for output control
Tip
The Cross Platform API surface is intentionally smaller. If your code references properties or methods that don't exist, the compiler will catch these at build time.
Call the export method
The final step is to export your report using the Cross Platform API exactly as before - with one minor change to the namespace. Here's a full example:
using DebwinLogger logger = new DebwinLogger(@"c:\logs\report.log", LogLevel.Info);
ListLabel listLabel = new ListLabel
{
Logger = logger,
DataSource = GetYourDataSource(), // e.g. DataSet, IEnumerable<T>, etc.
AutoProjectFile = Path.Combine(destinationPath, "YourConvertedProject.json"),
LicensingInfo = "YOUR-LICENSING-KEY"
};
var exportConfig = new ExportConfiguration(
LlExportTarget.Pdf,
@"c:\exports\report.pdf",
listLabel.AutoProjectFile
);
exportConfig.ShowResult = true;
// Execute export
listLabel.Export(exportConfig);
Tip
You can also export to other targets (PNG, JPEG, streaming to Stream, etc.) by choosing the appropriate LlExportTarget and overloads of Export.
Testing and validation
Thorough testing is critical for a successful migration. Use this systematic approach:
1. Visual comparison testing
Export reports side-by-side
Generate the same report using both Classic and Cross Platform, then compare:
- Text positioning and font rendering
- Image quality and scaling
- Chart rendering (if supported)
- Page breaks and multi-page layouts
Expected differences
Minor rendering differences may occur due to different rendering engines (GDI+ vs. SkiaSharp). These are usually acceptable if content and layout are functionally equivalent.
2. Functional testing
Data binding validation
- Verify all fields populate correctly
- Test with empty or null data
- Check date and number formatting
Expression evaluation
- Validate all formulas and calculations
- Test conditional visibility and formatting
- Verify aggregate functions (sum, count, etc.)
Relationship handling
- Confirm master-detail relationships work correctly
- Test nested tables and sub-reports
3. Performance testing
Benchmark report generation
- Measure time to generate representative reports
- Test with production-like data volumes
- Identify any performance regressions
4. Integration testing
End-to-end workflows
- Test the complete reporting pipeline in your application
- Verify error handling and logging
- Confirm output file delivery (storage, etc.)
Important
Do not migrate to production without testing all reports with production-like data. Differences in rendering or unsupported features may only appear with specific data patterns or layouts.
Common migration pitfalls
Assuming feature parity
Pitfall: Expecting all Classic Edition features to work in Cross Platform.
Solution: Review the limitations before starting. Test a representative subset of reports early to identify unsupported features.
Skipping visual validation
Pitfall: Assuming converted reports render identically without visual inspection.
Solution: Export and manually review all reports. Automated testing catches data issues but not layout problems.
Inadequate error handling
Pitfall: Not handling ListLabelException or missing log output.
Solution: Implement comprehensive error handling and enable logging from the start (see Debugging and troubleshooting).
Ignoring platform dependencies
Pitfall: Not including required native libraries (like SkiaSharp.NativeAssets.Linux) on Linux.
Solution: Test deployment on target platforms early. Container-based testing helps catch platform-specific issues.
Underestimating migration time
Pitfall: Treating migration as a simple package swap.
Solution: Budget time for conversion, testing, and addressing incompatibilities. Complex applications may require substantial rework.
Next steps
- Testing: Run all your existing reports and compare outputs against the classic version using the strategies outlined above.
- Troubleshooting: See Debugging and troubleshooting for common issues.
- Deployment: Ensure your deployment pipeline includes the
combit.ListLabel31.CrossPlatformpackage and any native runtime assets (e.g.,SkiaSharp.NativeAssets.Linuxon Linux).