Working with the object model
The List & Label Cross Platform object model (DOM) enables programmatic creation, inspection, and modification of report projects. It provides full control over report elements when generating or transforming reports dynamically at runtime.
What is the DOM?
The DOM is a programmatic representation of report projects. It exposes report structure—regions, objects, styles, parameters—as .NET classes that you can read, create, modify, or delete at runtime.
The DOM is built on a JSON-based project structure, which means:
- Projects are serializable and diffable
- Changes can be versioned and code-reviewed
- No binary format dependencies
When do you need the DOM?
Use the object model when you need to:
Create report layouts programmatically
Generate reports from templates or computed structures without manual design.Transform existing projects at runtime
Modify layouts based on user preferences, data characteristics, or deployment environment.Build dynamic reporting workflows
Construct reports from reusable components, apply conditional logic, or merge templates.Automate report maintenance
Apply bulk changes to many reports (e.g., style updates, field renaming).
Note
Most reporting scenarios do not require DOM manipulation. Static project files created in the classic designer and used via AutoProjectFile are simpler and sufficient for most use cases.
When to prefer static projects over DOM
| Scenario | Use static project | Use DOM |
|---|---|---|
| Fixed report layout | ✓ | |
| Designer-created templates | ✓ | |
| Content varies, layout stays same | ✓ | |
| Layout changes based on data/rules | ✓ | |
| Programmatic report generation | ✓ | |
| Automated bulk transformations | ✓ | |
| Merging or composing templates | ✓ |
Important
DOM manipulation requires deeper understanding of LLCP internals and introduces complexity. Start with static projects and switch to DOM only when runtime layout changes are necessary.
Learning curve and complexity
DOM editing is powerful but complex.
You need to understand:
- Report structure (regions, objects, sub-items, lines)
- Layout units (SCM—1/1000 mm)
- Property dependencies and constraints
- Serialization and lifecycle management
Expect higher development time and more testing compared to static projects.
Tip
To learn DOM structure, open an existing project using OpenProject, inspect its objects, and experiment with small changes before building complex workflows.
Opening and creating projects
To start working with DOM, first open or create a project using the ListLabel.OpenProject method:
ListLabel listLabel = new ListLabel
{
DataSource = GetNorthwindDataSet(),
AutoProjectFile = projectFilePath,
LicensingInfo = "..."
};
using var project = listLabel.OpenProject(
projectFilePath,
LlDomFileMode.OpenOrCreate,
LlDomAccessMode.ReadWrite,
LlProject.List
);
Tips:
- Wrap the project object in a
usingstatement to ensure proper disposal. - If the project file does not exist,
OpenOrCreatewill create a new instance.
Understanding DOM basics
Once a project is open, you can:
- inspect existing objects
- add new objects
- modify properties
- remove objects
All DOM items reflect JSON-based project parts such as fonts, parameters, regions, objects, and layout metadata.
For a full reference of available classes, see the combit.Reporting.Dom namespace documentation.
Adding objects
Example: Add a text object
ObjectText text = new ObjectText(project.Objects);
// Set position and style
Size pageExtent = project.Regions[0].Paper.Extent.Get();
text.Position.Set(10000, 10000, pageExtent.Width - 65000, 27000);
// Add content
Paragraph paragraph = new Paragraph(text.Paragraphs);
paragraph.Contents = "\"Hello World\"";
paragraph.Font.Bold = "True";
Creating a table
The following example adds a container and populates it with a table and fields:
// Create a report container
ObjectReportContainer container = new ObjectReportContainer(project.Objects);
container.Position.Set(10000, 40000, pageExtent.Width - 20000, pageExtent.Height - 44000);
// Add a table
SubItemTable table = new SubItemTable(container.SubItems);
table.TableId = "YourTableName";
// Add a new data line including all selected fields
TableLineData tableLineData = new TableLineData(table.Lines.Data);
TableLineHeader tableLineHeader = new TableLineHeader(table.Lines.Header);
// Example list of fields (replace with actual field names)
List<string> fieldNames = new List<string> { "Field1", "Field2", "Field3" };
foreach (string fieldName in fieldNames)
{
string fieldWidth = (Convert.ToInt32(container.Position.Width) / fieldNames.Count).ToString();
// Define header line
TableFieldText header = new TableFieldText(tableLineHeader.Fields);
header.Contents = string.Format("\"{0}\"", fieldName);
header.Filling.Style = "1";
header.Filling.Color = "LL.Scheme.BackgroundColor2";
header.Font.Bold = "True";
header.Font.Color = "LL.Color.White";
header.Width = fieldWidth;
// Define data line
TableFieldText tableField = new TableFieldText(tableLineData.Fields);
tableField.Contents = $"{sourceTableName}.{fieldName}";
tableField.Width = fieldWidth;
tableField.Filling.Pattern = "0";
}
This pattern is common when transforming dynamic data sources into structured report layouts.
Saving and exporting
When the project is open in write mode, save changes:
project.Save();
After making changes you can export the project
Best practices and common pitfalls
Best practices
Start from an existing project
Instead of building reports from scratch, open a designer-created project and modify it. This reduces errors and provides a working baseline.
Use disposal patterns correctly
Always wrap project objects in using statements to ensure proper cleanup, especially when opening multiple projects in sequence.
Understand SCM units
Layout coordinates use SCM (1/1000 mm). To convert to cm: divide by 10,000. Example: 20,000 SCM = 2 cm.
Test after each change
Export and visually verify the report after modifying the DOM. Small mistakes in object positioning or properties can cause unexpected results.
Version control JSON projects
Store JSON project files in version control to track changes and enable rollback.
Common pitfalls
Forgetting to save changes
Changes to DOM objects are not persisted until project.Save() is called.
Incorrect coordinate calculations
Mixing units or forgetting to account for page margins can cause objects to be positioned off-page.
Property type mismatches
Many DOM properties expect strings (e.g., "True" not true). Check property types carefully.
Modifying read-only projects
Opening a project in ReadOnly mode and attempting to modify it will fail. Use ReadWrite mode for edits.
Not handling disposal
Failing to dispose project objects can lead to resource leaks in long-running applications.
Tip
When debugging DOM issues, enable logging (see Debugging and troubleshooting) to trace property changes and validation errors.
See also
- Dynamic report construction – Full example building a report layout entirely through the DOM without a pre-designed template.
- Getting started
combit.Reporting.Domnamespace reference- Migrating from Classic Edition