---
title: Validate bound objects and report errors
summary: Push pending control edits, trigger business-object rule evaluation, harvest and aggregate error messages, and re-style controls.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-17
library: SAIF.Presentation.Web.Binding.Infragistics111
reference_type: package
operation_id: OP-BIND-005
trigger: "`binder.Validate()` (or `RefreshValidation()`), typically on Save"
---

# Validate bound objects and report errors

Push pending control edits, trigger business-object rule evaluation, harvest and aggregate error messages, and re-style controls.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-BIND-005 |
| **Trigger** | `binder.Validate()` (or `RefreshValidation()`), typically on Save |
| **Inputs** | Registered binders, registered validation objects |
| **Outputs** | `Boolean` overall validity; populated `ErrorLabel` / `SAIFMessage`; controls re-styled; `FirstControlWithError` set |
| **Primary components** | `clsObjectBindManager.Validate`, `ValidateBindSources`, each binder's `GetErrors`, `clsCustomValidator.PerformValidation`, `clsObjectBinderBase.SetControlFormat` |
| **Entry point** | `SAIF.Presentation.Web.Binding.Infragistics111/clsObjectBindManager.vb` |

## Steps

1. Call `BindToObject()` so that non-event-driven controls have pushed their values before validation (see [Pull control values back into objects](pull-control-values-into-objects.md)). ([BR-BIND-027](../business-rules.md#br-bind-027-validation-writes-back-before-checking))
2. Clear the aggregated error list and reset `m_FirstErrorControl`. ([BR-BIND-028](../business-rules.md#br-bind-028-validation-clears-prior-error-state))
3. Call `ValidateBindSources()`, which iterates every registered validation object, resolves its `IsValid` property via `TypeDescriptor` and reads it. Reading `IsValid` is what causes the SAIF BOF business object to run its rules and populate its error messages.* ([BR-BIND-029](../business-rules.md#br-bind-029-reading-isvalid-triggers-rule-evaluation))
   - Delegates to the business object's `IsValid` implementation (`clsBusinessBase` / `clsBusinessCollectionBase`, `SAIF.Framework.Core`): broken rules evaluated by `clsRulesManager` make `IsValid` `False` and populate the object's broken-rules collection.†

> **Origin**: This rule-evaluation step is implemented in `SAIF.Framework.Core` / `clsBusinessBase` and executed on behalf of this operation; its internal steps are not visible from this repository.**

4. For each binder: if it is a custom validator, call `PerformValidation()`; otherwise call `GetErrors()`. ([BR-BIND-030](../business-rules.md#br-bind-030-custom-validators-run-delegate-others-harvest-idataerrorinfo))
5. `GetErrors` selects the property/object pair to inspect — the validation property/source for a dual binder, otherwise the bind property/source — casts the object to `IDataErrorInfo`, and reads `Item(property)`. ([BR-BIND-031](../business-rules.md#br-bind-031-dual-binder-validates-its-validation-pair))
6. When the error text is non-empty, set the binder's error flag, split the text on CRLF, strip `<BR>` markup from each fragment, and add each non-blank fragment to the binder's `ControlErrors`. ([BR-BIND-032](../business-rules.md#br-bind-032-error-text-split-and-br-stripped)) ([BR-BIND-033](../business-rules.md#br-bind-033-non-empty-error-text-flags-control))
7. For a binder with errors: set the overall result to `False`, add each message to the manager's error list **only if not already present**, record the binder's control as `FirstControlWithError` if none has been recorded yet, and call `SetControlFormat(False)`. ([BR-BIND-034](../business-rules.md#br-bind-034-duplicate-messages-reported-once)) ([BR-BIND-035](../business-rules.md#br-bind-035-first-error-control-recorded))
8. For a binder without errors: call `SetControlFormat(True)`, except when the binder's control is the already-recorded first error control (so an error-styled control is not reset by a second, clean binding on the same control). ([BR-BIND-036](../business-rules.md#br-bind-036-clean-binder-preserves-first-error-control-formatting))
9. `SetControlFormat(False)` applies `errorbordercolor` to multiline text boxes and check boxes, `errorbackcolor` to everything else, and leaves `UltraWebGrid` / `WebDataGrid` untouched. ([BR-BIND-037](../business-rules.md#br-bind-037-error-styling-by-control-type)) ([BR-BIND-038](../business-rules.md#br-bind-038-grids-never-styled-at-control-level))
10. `SetControlFormat(True)` leaves any control already styled `disabledbackcolor` untouched, sets `normal` on labels, clears the class on check boxes, skips grids, and otherwise applies `defaultbackcolor`. ([BR-BIND-039](../business-rules.md#br-bind-039-disabled-controls-not-restyled-on-success)) ([BR-BIND-040](../business-rules.md#br-bind-040-valid-styling-by-control-type))
11. Assign `FormattedErrorMessage` — the distinct messages joined by `<BR>` — to `ErrorLabel.Text` and `SAIFMessage.Text` when those properties are set. ([BR-BIND-041](../business-rules.md#br-bind-041-distinct-messages-joined-with-br)) ([BR-BIND-042](../business-rules.md#br-bind-042-formatted-message-written-to-configured-controls))
12. Return `True` only when no binder reported an error.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start([Validate / RefreshValidation]) --> S1[BindToObject]
	S1 --> S2[Clear error list and first-error-control]
	S2 --> D0{RefreshValidation?}
	D0 -->|No| S3[ValidateBindSources: read IsValid on each source]
	D0 -->|Yes| S4[Skip source validation]
	S3 --> S5[For each binder: GetErrors or PerformValidation]
	S4 --> S5
	S5 --> D{Errors found?}
	D -->|Yes| S6[Aggregate distinct messages<br>SetControlFormat False]
	D -->|No| S7[SetControlFormat True]
	S6 --> S8["ErrorLabel.Text / SAIFMessage.Text = FormattedErrorMessage"]
	S7 --> S8
	S8 --> End([Return overall validity])
```

## Failure and edge-case behavior

- `RefreshValidation()` repeats steps 1, 2 and 4–12 above but **omits** step 3 (`ValidateBindSources`), so it re-renders existing error state without asking the business objects to re-evaluate ([BR-BIND-043](../business-rules.md#br-bind-043-refreshvalidation-skips-bind-source-revalidation)).
- A property-type custom validator delegate appends messages to `ControlErrors` directly, but `PerformValidation` never sets the binder's internal error flag in that branch — so those messages do not mark the binder as erroring and may not surface through `Validate()`.*

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

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified. Statements marked with † were retrieved from dependency library documentation via the Legends CLI RAG service.

## Sources
- SAIF.Presentation.Web.Binding.Infragistics111/clsObjectBindManager.vb
