ComponentOne DataObjects for .NET
Events on Modifying Row
DataObjects for .NET (Enterprise Edition) > Business Logic > Business Logic Events > Events on Modifying Row

The sequence of events invoked when the end user or user code modifies a field is as follows:

  1. Field-level constraints are tested. If a constraint is not satisfied (does not evaluate to True), an exception is thrown and the change aborted. In a constraint expression, the field being modified returns the new (proposed) value, although the value has not yet been assigned to the field. If you need the old value of the field in an expression, use a special function: BeforeChange(field) (see DataObjects for .NET Expressions).
  2. The BeforeFieldChange event fires. This event allows you to specify validation logic that cannot be specified in the form of constraint expressions. Throwing an exception in this event aborts the change. When this event is fired, the field value is not yet modified. The new (proposed) values are available in the NewValue argument of the event.
  3. The new value is assigned to the field.
  4. Any calculated fields (Calculation expression) dependent on the modified field acquire their new values immediately after the new value is assigned to the field (before the AfterFieldChange event). In fact, DataObjects for .NET does not perform any special processing in order to update calculated fields after changing the value. It simply marks the calculation results that depend on the changed value, internally, as out-of-date. Whenever a calculated value is requested, in code, or by a bound control, for display, the calculation expression is re-evaluated to obtain the up-to-date value. Note that bound controls are not notified of the change until the whole process of handling the field modification is completed. Only after all necessary changes are done, bound controls will be notified of all changes resulting from the field modification, including the calculated expressions that have gone out-of-date. At that point, the bound control will request the new values, so the calculation expressions will be re-evaluated. If, for some reason, you need to force re-evaluation of calculated expressions before that, it can be done calling the Refresh method for a single row or Refresh for a whole rowset.
  5. The AfterFieldChange event fires. This event allows you, among other possible actions, to modify other fields/rows/tables depending on this field, for example, update some counters. The new value is already assigned to the field, and the old field value is also available in this event, in its OldValue argument. This can be useful, for example, in updating counters, where you may need to add the new value and subtract the old one.
  6. At this point, after the AfterFieldChange event is handled, the process of changing a field value is finished. However, that does not mean that DataObjects for .NET has finished the processing and relinquished control to the user. The business logic code that handled the events could make other changes to row fields in the process, or it could change other rows or other tables. When this handling is done, DataObjects for .NET collects all changed rows, all changes resulting from the field modification, and fires the AfterChanges event for each such row. If the business logic code did not change any fields in rows other than the row where the original field change occurred, then AfterChanges will fire for that row only. If, however, other changes resulted from the field modification, AfterChanges will fire for all changed rows. The AfterChanges event is designed specifically to ensure that this is the "last change", so the developers can put code that relies on the "finality" of changes there. For instance, this event is the best place to put your code calculating some calculated field values (supposedly, for calculations that cannot be specified as simple calculation expressions).
  7. The CurrentRowChanged event fires with ChangeType set to RowChangedTypeEnum.FieldsChanged. Strictly speaking, this event is not a part of business logic, because it is fired in client components, such as C1DataSet, not in data library components. It is used in the client application for GUI purposes, in scenarios like, for example, synchronizing detail data with the master row on every change occurring in the master row.
  8. Finally, DataObjects for .NET notifies bound controls of all changes that occurred during the processing of field modification, so they can update their display with new data. Notifying bound controls does not occur immediately when you change a field in your business logic code. It is postponed until the end, because a field modification can cause other changes (see above), so it is better, in more senses than one, to notify of all changes at once, when they are final.