protected void PopulateDataTable(DataTable dt, List <Field> fields) { foreach (Field field in fields.Where(f => f.IsTableField)) { // Only create columns in the underlying data table for those properties in the model that have Column or DisplayField attributes. // Otherwise, we start tracking things like EntityRef properties, etc, that we don't want to track! ExtDataColumn dc; // Handle nullable types by creating the column type as the underlying, non-nullable, type. if (field.Type.Name == "Nullable`1") { dc = new ExtDataColumn(field.Name, field.Type.UnderlyingSystemType.GenericTypeArguments[0], field.Visible, field.IsColumn, field.Lookup); } else { dc = new ExtDataColumn(field.Name, field.Type, field.Visible, field.IsColumn, field.Lookup); } dc.ReadOnly = field.ReadOnly; dc.Caption = field.DisplayName; dt.Columns.Add(dc); } }
protected virtual void Table_ColumnChanged(object sender, DataColumnChangeEventArgs e) { 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) { 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); // If it's actually a column in the table, then persist the change. ExtDataColumn edc = (ExtDataColumn)e.Column; if (edc.IsDbColumn) { Update(instance); } } } }
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); } // TODO: CAN PROBABLY BE REMOVED NOW THAT WE HAVE THE MODEL MANAGER SETTING THE PROGRAMMATIC FLAG. // 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. 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) { Update(instance); } } } 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); } } } }