---
title: Validate bound controls
summary: Aggregates validation errors across all bound controls and applies error/valid CSS formatting.
status: draft
owner: SAIF documentation team
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.Binding.Infragistics103
reference_type: embedded
operation_id: OP-BIND-004
trigger: Explicit call from consuming page, typically before a save/submit action
---

# Validate bound controls

This operation synchronizes control values into their bound objects, harvests validation errors from each bound business object via `IDataErrorInfo`/`IsValid`, aggregates the unique error messages, and applies error/valid CSS formatting to the corresponding controls.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-BIND-004 |
| **Trigger** | Explicit call to `Validate()` or `RefreshValidation()` from the consuming page |
| **Inputs** | Current `m_Bindings`, `m_ValidationObjects` |
| **Outputs** | `Boolean` overall valid/invalid result; populated `m_Errors`; control CSS formatting; `ErrorLabel`/`SAIFMessage` text |
| **Primary components** | `clsObjectBindManager.Validate`, `clsObjectBindManager.RefreshValidation`, `clsObjectBinderBase.GetErrors`, `clsObjectBinderBase.SetControlFormat` |
| **Entry point** | `SAIF.Presentation.Web.Binding.Infragistics103\clsObjectBindManager.vb` |

## Steps

1. Call `BindToObject()` to sync non-event-driven controls into their objects (see [Control to object data pull](control-to-object-pull.md)).
2. Clear `m_Errors` and reset `m_FirstErrorControl`.
3. (`Validate()` only) Call the private `ValidateBindSources()`: for each distinct object in `m_ValidationObjects`, reflectively read its `IsValid` property if present — this forces framework business objects to (re)compute their rule state; the result is read but not otherwise branched on in this method body.*
4. Iterate `m_Bindings`: for each binder, call `PerformValidation()` if `IsCustomValidator` is true (custom validator delegate/Object-mode `IsValid` check), else call `GetErrors()` (reads `IDataErrorInfo.Item(property)` on the bound/validation object, splits on `vbCrLf`, strips `<BR>` tags, populates `ControlErrors`).
5. If the binder has errors:
   - Mark the overall result invalid.
   - Add unique error strings to `m_Errors` ([BR-BIND-005](../business-rules.md#br-bind-005-duplicate-error-message-suppression)).
   - Record `m_FirstErrorControl` if not already set.
   - Call `Binder.SetControlFormat(False)` — applies `errorbackcolor`/`errorbordercolor` CSS, skipping grids/checkbox-lists ([BR-BIND-002](../business-rules.md#br-bind-002-gridlist-controls-exempt-from-cell-level-errorvalid-css)) and varying by `TextBox.MultiLine` state ([BR-BIND-003](../business-rules.md#br-bind-003-multi-line-textbox-error-styling-differs-from-single-line)).
6. If the binder has no errors, apply valid CSS via `SetControlFormat(True)` ([BR-BIND-001](../business-rules.md#br-bind-001-error-css-suppression-for-protected-fields)), unless the binder's control is the same as `m_FirstErrorControl` ([BR-BIND-004](../business-rules.md#br-bind-004-first-error-control-precedence-during-formatting)).
7. If `ErrorLabel` is set, write `FormattedErrorMessage` (all unique errors joined with `<BR>`) to it; likewise for `SAIFMessage` if set.
8. Return the overall boolean result.
9. `RefreshValidation()` follows the identical sequence but omits step 3 (`ValidateBindSources()`), per its stated purpose of refreshing control formatting without re-validating bind sources.
10. No SQL/table interaction occurs; no delegation into a referenced-library operation beyond invoking the bound business object's own `IDataErrorInfo`/`IsValid` members (defined in `SAIF.BOF.Framework`, outside this library's source — treated as an external/framework call, not traced further).*

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Validate/RefreshValidation called]) --> Bind[BindToObject: sync controls to objects]
	Bind --> Reset[Clear m_Errors, reset m_FirstErrorControl]
	Reset --> Refresh{Is this RefreshValidation?}
	Refresh -->|No| ValidateSources[ValidateBindSources: read IsValid per distinct object]
	Refresh -->|Yes| IterateBinders[Iterate m_Bindings]
	ValidateSources --> IterateBinders
	IterateBinders --> Custom{IsCustomValidator?}
	Custom -->|Yes| PerformValidation[PerformValidation]
	Custom -->|No| GetErrors[GetErrors: read IDataErrorInfo]
	PerformValidation --> HasErrors{Errors found?}
	GetErrors --> HasErrors
	HasErrors -->|Yes| MarkInvalid[Mark invalid, add unique errors, format error CSS]
	HasErrors -->|No| FormatValid[Format valid CSS unless first-error control]
	MarkInvalid --> More{More binders?}
	FormatValid --> More
	More -->|Yes| IterateBinders
	More -->|No| WriteLabel[Write aggregated errors to ErrorLabel/SAIFMessage]
	WriteLabel --> EndResult([Return overall valid/invalid])
```

## Failure and edge-case behavior
- A distinct bound object with no `IsValid` property is skipped without error during `ValidateBindSources()`.*
- Error text containing `<BR>` tags is stripped before being added to the aggregated error collection.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `SAIF.Presentation.Web.Binding.Infragistics103\clsObjectBindManager.vb`
- `SAIF.Presentation.Web.Binding.Infragistics103\clsObjectBinderbase.vb`
