zplCore.comzplCore.com

LabelBinding<T>

public sealed class LabelBinding<T>

Strongly typed, streaming mass data binding of a Label to C# objects. Works with anything enumerable: lists, LINQ queries, EF Core IQueryable (sync) or AsAsyncEnumerable() (async), so millions of records never have to be in memory at once.

Thread safety: once configured, ToZpl/Generate/Render may be called from several threads concurrently (the label template is only read); configuration methods (Map, Copies, ...) are not thread-safe.

Methods

Method SignatureReturnsDescription
# Across(int columns, double gap = 0, double leftOffset = 0)LabelBinding<T>Multi-across media: places columns records side by side in one format (e.g. 3 labels per row on 100 mm wide liner), separated by gap (label units).
# Batches(IEnumerable<T> records, int labelsPerBatch = 500, int dpi = 203)IEnumerable<string>Groups the generated ZPL into batches of labelsPerBatch records (one network write each).
# Copies(Func<T, int> copies)LabelBinding<T>Number of printed copies per record (^PQ), e.g. o => o.Quantity.
# CountQueryableWith(Func<IQueryable<T>, int> counter)LabelBinding<T>Counts IQueryable sources before streaming, e.g. q => q.Count() (one extra COUNT query; the records themselves are enumerated only once).
# CutAfterLastLabel(bool cut = true)LabelBinding<T>Cut only after the last label of the job: all formats print in tear-off mode (^MMT), the last one in cutter mode (^MMC). Default: Label.CutAfterLastLabel.
# Generate(IEnumerable<T> records, int dpi = 203)IEnumerable<string>Lazily yields ZPL: leading label, ^DF template, one format per record, trailing label.
# Generate(IEnumerable<T> records, int dpi, int? recordCount)IEnumerable<string>Like LabelBinding.Generate with an explicit record count (null = automatic).
# GenerateAsync(IAsyncEnumerable<T> records, int dpi = 203, CancellationToken ct = default)IAsyncEnumerable<string>Async counterpart of LabelBinding.Generate for streamed sources (database readers, APIs).
# GenerateAsync(IAsyncEnumerable<T> records, int dpi, int? recordCount, CancellationToken ct = default)IAsyncEnumerable<string>Async generation with a known record count (e.g. from a separate COUNT query) for the leading label and TOTAL_PAGES.
# Job(string name, Func<T, string>? key = default)LabelBinding<T>Name and key (e.g. tracking number) used for PrintJobInfo.
# Map(string field, Func<T, object> selector)LabelBinding<T>Binds a data field name (as used in LabelItem.DataField or [Name] in expressions) to a lambda.
# MapItem(string itemName, Func<T, object> selector)LabelBinding<T>Binds the item with the given LabelItem.Name to a lambda (sets its DataField to the name).
# OnProgress(Action<LabelProgress> progress)LabelBinding<T>Called once per printed label of the records (copies included; not for leading/trailing labels), in label order, when the label's format is handed out – also when formats are built in parallel. Runs on the thread that enumerates the job (LabelBinding.Generate, ToZpl, Write, Print, Render), so keep it short.
# PrintAsync(ZplPrinterClient printer, IAsyncEnumerable<T> records, int labelsPerBatch = 500, int dpi = 203, IProgress<int>? progress = default, CancellationToken ct = default)Task<int>Prints all records in batches over one connection per batch. Returns the number of records.
# PrintAsync(ZplPrinterClient printer, IEnumerable<T> records, int labelsPerBatch = 500, int dpi = 203, IProgress<int>? progress = default, CancellationToken ct = default)Task<int>Prints all records in batches (record count known up front). Returns the number of records.
# PrintAsync(ZplPrinterClient printer, IAsyncEnumerable<T> records, int? recordCount, int labelsPerBatch = 500, int dpi = 203, IProgress<int>? progress = default, CancellationToken ct = default)Task<int>Prints an async source with a known record count (leading label, TOTAL_PAGES).
# Render(IEnumerable<T> records, int dpi = 203, ZplOutputFormat format = ZplOutputFormat.Png)IEnumerable<byte[]>Lazily renders one encoded image per printed label (preview, PDF archive, e-mail ...). The leading items that are the same on every label (captions, frames, logos – up to the first item that varies) are rasterised once per job and every label is drawn over that image: the same pixels as rendering each label on its own.
# RenderPdf(IEnumerable<T> records, int dpi = 203)byte[]All labels as one multi-page PDF.
# RenderPdf(IEnumerable<T> records, int dpi, int imageQuality)byte[]All labels as one multi-page raster PDF with the given image quality: 101 = lossless, 1–100 = JPEG (see ZplRenderSettings.PdfImageQuality).
# ToZpl(IEnumerable<T> records, int dpi = 203)stringGenerates ZPL for all records (fine for small/medium jobs; use the Write/Stream methods for big ones).
# UseStoredFormat(string name = "R:ZPLCORE.ZPL")LabelBinding<T>Stores the label once in printer memory (^DF) and sends only the variable field values per record (^XF/^FN). Cuts the data volume for large jobs by typically 80–95 %.
# WithCulture(string culture)LabelBinding<T>Culture for {t:key} placeholders of this job (overrides Label.Culture).
# WithLeadingLabel(Label label)LabelBinding<T>Label printed before the records (bound to PrintJobInfo: JobName, Created, RecordCount if known, …).
# WithParallelism(int maxDegree)LabelBinding<T>Formats of a job are built on up to maxDegree threads at once, in blocks of records; the output order, counters and job information stay exactly as in sequential generation (1 = sequential). Default: all processors for record types whose fields are read without caller code – dictionaries (also JSON-like nested values), JsonElement, JsonNode, DataRow, strings and primitives – and no caller code in the job (LabelBinding.Map functions, custom expression functions, type references, a custom clock). Classes (POCOs) are read through their property getters, which may load data lazily (e.g. Entity Framework proxies sharing one DbContext): those jobs are sequential unless set here.
# WithRecordCount(int? count)LabelBinding<T>Known number of records for streamed sources (shown on the leading label as RecordCount and available as TOTAL_PAGES). Collections are counted automatically; an explicit count passed to Generate/Write overrides this.
# WithTrailingLabel(Label label)LabelBinding<T>Label printed after the records (bound to PrintJobInfo incl. RecordCount, LabelCount, FirstKey, LastKey).
# WriteZpl(IEnumerable<T> records, TextWriter writer, int dpi = 203)voidStreams ZPL for all records to a writer (file, network stream ...).
# WriteZplAsync(IAsyncEnumerable<T> records, TextWriter writer, int dpi = 203, CancellationToken ct = default)TaskStreams ZPL from an async source, e.g. EF Core query.AsAsyncEnumerable().
# WriteZplAsync(IAsyncEnumerable<T> records, TextWriter writer, int dpi, int? recordCount, CancellationToken ct = default)TaskStreams ZPL from an async source; recordCount (if known) is shown on the leading label and as TOTAL_PAGES.
# WriteZplAsync(IAsyncEnumerable<T> records, Stream stream, int dpi = 203, int? recordCount = default, CancellationToken ct = default)TaskWrites UTF-8 ZPL for an async source to a stream with asynchronous writes only (safe for ASP.NET Core Response.Body, which forbids synchronous IO).
# WriteZplAsync(IEnumerable<T> records, Stream stream, int dpi = 203, int? recordCount = default, CancellationToken ct = default)TaskWrites UTF-8 ZPL for a (sync) source to a stream with asynchronous writes only. The record count is taken from collections automatically.
# WriteZplAsync(IAsyncEnumerable<T> records, PipeWriter writer, int dpi = 203, int? recordCount = default, CancellationToken ct = default)TaskWrites UTF-8 ZPL to a PipeWriter (e.g. ASP.NET Core Response.BodyWriter).
# WriteZplAsync(IEnumerable<T> records, PipeWriter writer, int dpi = 203, int? recordCount = default, CancellationToken ct = default)TaskSync-source variant of the PipeWriter overload.