The Premise, Restated for Cells
In a hand-built WinForms screen, a cell is whatever the designer decided during development: text, checkbox, combo, or another compiled type. Turning that text cell into a searchable lookup, making it read-only for one group of users, or adding an AI proofreader usually means reopening the designer, wiring events, rebuilding, testing, and redeploying.
ITS Framework moves that decision into data. For each column in a view, one VS row can carry:
- The cell type through
clt. - A pointer to editor metadata through
edtr_id. - Static and expression-driven read-only rules.
- Fonts, colors, alignment, format, wrapping, and width.
- Row-scoped variations that can change how the same column behaves for different records.
The number of fields is small compared with the surface of the Visual Studio designer. Their strength comes from composition. A cell type, an editor definition, a filter, a permission rule, and a conditional style can be resolved together at runtime to express behavior that would otherwise be scattered across designer files and event handlers.
The cell is not a passive rectangle. It is a control whose contract happens to be stored in a row.
The clt Field: Cell Types in One Integer
Every configured column style carries a clt integer. It is the discriminator that tells CntrlG which DataGridViewCell behavior or CellCtrlEdtr subclass to use.
clt | Renders as | Interaction | Typical use |
|---|---|---|---|
| 0 | Plain text | Single-line edit | General string columns |
| 1 | Combo box | Selects from a bound dataset | Foreign keys and enumerations |
| 2 | Date or time picker | Typed date editing | DateTime columns with a custom format |
| 3 | Masked numeric editor | Validated numeric entry | Currency, percentages, and quantities |
| 4 | Multiline text | Wrapped, auto-height edit | Notes, descriptions, and addresses |
| 5 | Formatted display | Read-only | Computed and as-if fields |
| 6 | Hyperlink or active cell | Click executes an action | Open document, send email, or show map |
| 7 | Link plus inline editor | Dialog edits and writes back | Searches, calculators, subforms, and AI editors |
| 8 | Tri-state checkbox | Boolean edit | Nullable booleans |
| 9 | Image or thumbnail | Display or preview | Photos and icons resolved from type_id |
The catalog is intentionally compact and extensible. A business module can register a focused CellCtrlEdtr subclass for a color picker, signature capture, or barcode scanner. Most screens, however, rely on only a handful of established types: text, combo, date, hyperlink, and custom editor.
The consuming module does not need a switch statement for those established behaviors. Setting clt=1 and pointing edtr_id to a lookup definition is enough for the runtime to materialize a working combo cell.
Related Video: The Same Cell Contract in a Pivot Row
This live Entity Management example shows a User entity through CntrlP. The row is projected vertically, but its properties retain the same configured cell editors used by CntrlG: the orientation changes while the editor contract stays intact.
What to watch: User entity at 00:00 · ComboBox at 00:03 · checkboxes at 00:08 · date picker at 00:10 · audit history at 00:12. The production capture was reviewed before publication and confidential information was removed.
Populating Cells: Three Reusable Recipes
Free text, formatted and validated
clt = 0
cf = "### ### ####"
mw = 100
w = 140
ro = false
Val = regular expression + multilingual Message Code
The plain text editor formats during painting, validates on commit, and can display a red error indicator with a translated message when the value fails its rule. The same recipe can use C2 for currency or MM/dd/yyyy when a date is intentionally rendered as text.
Combo bound to a lookup dataset
clt = 1
edtr_id = CountryLookup
dataset = Countries
value = id
display = name
secondary = code + " - " + name
filter = active=1 AND tenant_id={|tenant_id|}
The editor metadata identifies a named DAL dataset, value and display members, and an optional filter. Tokens in that filter are resolved from the current DataRow. The combo can therefore use cached reference data, constrain its choices to the row context, and write the selected key directly into the underlying DataColumn.
Search dialog, autocomplete, or inline editor
clt = 7
edtr_id = MemberSearch
view = VMemberSearch
dataset = Members
mapping = id|name:member_id|member_name
selection = single
The framework-provided CellCtrlEdtrSearch opens the configured view, searches its dataset, and projects the selected values back into the current row according to the mapping. The dialog is itself a CntrlV; its columns are CntrlG cells, and any of those cells can open another configured editor. The mechanism is recursive because every level consumes the same contracts.
AI-Assisted Text as a First-Class Cell Capability
The L2 ITSAI service can sit behind the same editor contract. A reusable CellCtrlEdtrAIProof implementation sends the current value to the AI service and returns a corrected or enriched value. An Edtr row supplies the prompt template, model selection, execution mode, and any audit-column mapping.
VS.clt = 7
VS.edtr_id = AI_MedicalProofread
Edtr prompt = MedicalProofread
Edtr mode = on-demand
Edtr original = ai_original
Edtr suggested = ai_suggested
Edtr accepted_by = ai_accepted_by
A clinical-notes cell can behave like an ordinary multiline editor until the user clicks its AI action. The framework sends the value, receives a proofread version and structured suggestions, and replaces or augments the value according to configuration. If audit fields are mapped, the original, suggestion, and accepting user remain available in the same row contract.
Nothing is hard-coded for the clinical-notes column. Converting a plain text cell into an AI-assisted cell means selecting an existing AI editor row and changing its VS reference. Translation, summarization, classification, and entity extraction use the same infrastructure; only the Edtr definition changes.
This configuration does not remove the need for governance. Sensitive data, prompt design, human review, model access, audit requirements, and failure behavior must still be defined at the service and policy levels. The point is that once a governed capability exists, individual views can consume it consistently through metadata.
Five Orthogonal Ways to Say Read-Only
Read-only behavior is not a single flag. IsReadOnly(cell, row) resolves several sources that answer different business questions:
- Column-level
ro: the column is always read-only in this view. A combo cell withro=truecan still resolve and display the label for its stored identifier. - View-level
ro: the entire grid is read-only. - Row-level expression:
D.FBool("no_updt")androw.EvalRO(expr)can lock a closed period, sealed record, or row owned by another tenant. - Per-cell expression: a cached conditional style can set
ro=trueonly when the current row matches a filter. A role-specific style can resolve the same condition differently for a supervisor. - Status validator: ambient
WFValidatorstate can feedReadOnlyByCntxt, allowing workflow context to suspend editing until a required command completes.
The chain is consulted when cells paint, begin editing, and execute actions. Because every input is data, the policy can vary by view, row, role, tenant, workflow state, and cell without embedding each combination in module code.
That flexibility increases the importance of diagnostics. Administrators need to see which rule won, which filter matched, and which permission or context made a cell read-only. Metadata-driven behavior is maintainable only when the runtime makes its resolution path observable.
Cell Styling: A Cell Is a Control
The properties a developer normally sets on a Label, TextBox, DateTimePicker, or ComboBox also exist in the VS contract:
- Colors:
bcandfcfor normal background and foreground;sbcandsfcfor selected cells. - Font:
f,fs, andfzfor family, size, and style, merged with the grid defaults byITSUtls.GetCellStyle. - Alignment:
aencodes the nineDataGridViewContentAlignmentvalues. - Wrapping:
wrenables multiline display and row auto-height. - Header appearance: header color and font fields allow the label to have its own visual hierarchy.
- Formatting:
cfcarries .NET format strings; a language-aware format can respect the active session culture. - Conditional overrides: row-filtered style records can change any of these values for matching data.
The same database column can therefore appear differently in two views. VClaims might render amount as ordinary right-aligned currency. VAccrualReport can show the same field in bold red above $50,000, gray at zero, and with a tooltip that explains the aging bucket. The underlying value remains the same DataRow field; each view supplies its own visual contract.
DataColumn + current DataRow
↓
baseline type and style
↓
VS column definition
↓
conditional row/cell overrides
↓
permissions + workflow context
↓
materialized DataGridViewCell + CellCtrlEdtr
Column Groups and Navigation Shortcuts
Enterprise grids can contain dozens of columns. ITS Framework allows the bound DataTable to include marker columns whose names follow a convention such as cl-sep_Financial_, cl-sep_Compliance_*, or cl-sep_Audit_**. They carry no business value; a DAL query can introduce one with a projection such as:
SELECT
claim_id,
claim_status,
NULL AS [cl-sep_Financial_*],
billed_amount,
paid_amount,
NULL AS [cl-sep_Compliance_**],
review_status,
reviewed_by
FROM dbo.Claim;
During binding, CntrlV.Nav() discovers the markers and populates BtnNav with entries that move horizontal scrolling to the next visible column. A trailing * can expose a fixed toolbar shortcut. A trailing ** can identify a floating shortcut whose label follows the section the user most recently visited.
The marker can also define a narrow tinted separator, creating a visual spine between logical groups. Adding a group is therefore a query-contract change rather than a new C# navigation handler. Because the query is resolved through the DAL, the available groups can still respect tenant and permission context.
What This Changes for the Super-User
A super-user who understands the business and can work safely with the Form Editor can perform changes that would otherwise become development stories:
- Add a column definition with its label, format, type, width, alignment, and read-only rule.
- Convert text to a lookup by changing
cltand selecting anedtr_id. - Open a configured search dialog from a cell and map selected values back to the row.
- Attach a governed AI proofreading or translation editor.
- Lock a row or cell when a business expression is true.
- Add a
Valrule for required values, positive amounts, email syntax, or contract dates. - Add a
VFfilter, aCmmcommand, or anMCtranslation. - Publish role-specific column presets and navigation groups.
When DAL.EvDSUpdated invalidates and refreshes the relevant configuration, a change can take effect at the next Init, even during an active session. The delivery bottleneck shifts away from repeated screen plumbing and toward correct business definitions.
That does not mean configuration should bypass governance. Production metadata should be validated, audited, promoted, and reviewed according to its risk. The advantage is not the absence of control; it is that recurring UI behavior has one governed representation instead of many bespoke implementations.
Where the Pattern Fits—and Where It Does Not
The ITS Framework desktop runtime targets .NET 10 for Windows and runs on controlled application servers close to SQL Server, while users connect through RDP or RDS. The WinForms runtime, DAL, metadata caches, and database operate inside a trusted enterprise environment. The client receives pixels, so this internal cell-to-database path does not require an HTTP/JSON boundary.
That environment makes rich DataSet contracts, cached lookup tables, direct WinForms binding, and structured persistence through stored procedures and UDTT or XML parameters economically sensible. It is a deliberate architecture for that deployment model, not a blanket recommendation.
A public browser application, offline client, untrusted network, or independently versioned partner integration needs explicit API contracts, transport security, independent versioning, and authorization boundaries. A metadata-driven cell runtime can still inspire those systems, but it should not erase boundaries that their operating environment requires.
There are also internal tradeoffs:
- Invalid metadata can move failures from compilation to initialization or screen-open time.
- Expression-driven permissions and styles require traceable precedence and diagnostic tools.
- New cell behavior still requires a reusable implementation before configuration can select it.
- AI editors require privacy controls, auditability, failure handling, and human review appropriate to the domain.
- Super-user access must be constrained by permissions and a disciplined promotion process.
From Cell to Application
A cell is a control. A column is a set of cell rules. A view combines column rules with commands and filters. A screen composes views. A module registers the screen and contributes only the behavior that metadata cannot express.
CntrlG makes that composition work at its smallest visible scale. When cell type is a field, read-only policy is an expression, an editor is a reference, and appearance is a merge of small values, adding a DateTimePicker and setting clt=2 become two ways of expressing the same intent.
That is data-first UI at cell level: recurring editors and behaviors are implemented once, then placed wherever the business needs them by changing the authoritative rows.