protected void OnRowChanging(IEnumerable <RowEvent> evt) { RowChanging?.Invoke(this, new RowEventArgs(evt)); }
protected virtual void Table_ColumnChanged(object sender, DataColumnChangeEventArgs e) { // Debugging //if (e.Row.Table.TableName == "EmsStationType") //{ //} if (!programmaticUpdate) { IEntity instance; if (e.Row.RowState == DataRowState.Detached) { instance = newInstance; } else { instance = items.SingleOrDefault(record => ((MappedRecord)record).Row == e.Row); } // Comboboxes do not fire a DataRowAction.Change RowChanged event when closing the dialog, // these fire only when the use changes the selected row, so we persist the change now if not // a detached record (as in, it must exist in the database.) if (e.Row.RowState != DataRowState.Detached) { // Use the column name that has changed, not the potential mapped column name. PropertyInfo pi = instance.GetType().GetProperty(e.Column.ColumnName); object oldVal = pi.GetValue(instance); // Prevents infinite recursion by updating the model only when the field has changed. // Otherwise, programmatically setting a field calls UpdateRowField, which changes the table's field, // which fires the ModelTable.Table_ColumnChanged event. This then calls back here, creating an infinite loop. if (((oldVal == null) && (e.ProposedValue != DBNull.Value)) || ((oldVal != null) && (!oldVal.Equals(e.ProposedValue)))) { // Always update the actual column, as the setter, for a mapped column, will probably update the // value for the mapped column. RowChangingEventArgs rowChangingArgs = new RowChangingEventArgs() { Entity = instance, ColumnName = e.Column.ColumnName }; RowChanging.Fire(this, rowChangingArgs); if (!rowChangingArgs.Handled) { if (rowChangingArgs.ReplaceInstance) { instance = rowChangingArgs.NewInstance; } modelMgr.UpdateRecordField(instance, e.Column.ColumnName, e.ProposedValue); } // If mapped, then update again, using the mapped column name. //if (((ExtDataColumn)e.Column).MappedColumn != null) //{ // PropertyInfo piMapped = instance.GetType().GetProperty(((ExtDataColumn)e.Column).MappedColumn); // object mappedColumnValue = piMapped.GetValue(instance); // modelMgr.UpdateRecordField(instance, ((ExtDataColumn)e.Column).MappedColumn, mappedColumnValue); //} // If it's actually a column in the table, then persist the change. ExtDataColumn edc = (ExtDataColumn)e.Column; if (edc.IsDbColumn || edc.MappedColumn != null) { RowChangedEventArgs rowChangedArgs = new RowChangedEventArgs() { Entity = instance, ColumnName = e.Column.ColumnName }; RowChanged.Fire(this, rowChangedArgs); if (!rowChangedArgs.Handled) { Update(instance); RowChangeFinalized.Fire(this, new RowChangeFinalizedEventArgs() { Entity = instance, ColumnName = e.Column.ColumnName }); } } } } else { // TODO: CAN PROBABLY BE REMOVED NOW THAT WE HAVE THE MODEL MANAGER SETTING THE PROGRAMMATIC FLAG. // If detached (not a real record in the DB yet) we want to update the model, but wait to persist (insert) the record // when the row editing is complete (Table_RowChange action is DataRowAction.Add). // Does changing a combobox for a detached row work? PropertyInfo pi = instance.GetType().GetProperty(e.Column.ColumnName); object oldVal = pi.GetValue(instance); // Prevents infinite recursion by updating the model only when the field has changed. // Otherwise, programmatically setting a field calls UpdateRowField, which changes the table's field, // which fires the ModelTable.Table_ColumnChanged event. This then calls back here, creating an infinite loop. if (((oldVal == null) && (e.ProposedValue != DBNull.Value)) || ((oldVal != null) && (!oldVal.Equals(e.ProposedValue)))) { modelMgr.UpdateRecordField(instance, e.Column.ColumnName, e.ProposedValue); } } } }