The code below shows the actual implementation of the
BaseSingleDataField class, which handles some of the basic functionality when
interacting with a single and simple interface data field. First, the
control's interface is created in the InitializeCell method. This method makes
the determination based on the current cell type, whether in read-only mode or
in edit/insert mode. Take a look below.
Listing 5
public override void InitializeCell(DataControlFieldCell cell,
DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
{
base.InitializeCell(cell, cellType, rowState, rowIndex);
Control control = null;
if (cellType == DataControlCellType.DataCell)
{
if (this.IsReadMode(rowState))
control = cell;
else
{
cell.Controls.Add(this.SetupEditControl());
if (!string.IsNullOrEmpty(this.GetDataItemFieldName(rowState)))
control = cell.Controls[0];
}
if (control != null && this.Visible)
control.DataBinding += new EventHandler(control_DataBinding);
}
}
At the beginning of this method is a reference to a control
variable. If in read-only mode, this variable then snags the reference to the
table cell (which the value is entered directly into the cell). If in edit or
insert mode, the SetupEditControl method creates a control that will represent
the edit/insert interface for the underlying data item.
At the end, if a control reference was successfully created
and this field is visible, the control creates an event handler for data binding.
The purpose of tapping into this event is to perform the binding to the actual
control. If in read-only mode, the sender control reference will be the table
cell; otherwise, it will match the edited control returned from
SetupEditControl.
Listing 6
void control_DataBinding(object sender, EventArgs e)
{
if (sender is TableCell)
{
TableCell cell = sender as TableCell;
cell.Text = this.GetReadOnlyValue(this.GetDataItemValue
(cell.NamingContainer, this.GetDataItemFieldName
(DataControlRowState.Normal)));
}
else
this.BindEditControl(sender, this.InsertMode);
}
Note that this method uses certain primitive base class
methods, notably the GetReadOnlyValue, GetDataItemValue, and the
GetDataItemFieldName methods. You can find these in the code sample attached. The
next method extracts the values back out of the interface controls, and adds it
to the dictionary.
In the GridView and DetailsView controls, a dictionary
contains the field names and their corresponding values. When updating, both
the old and new values are tracked, and insertions only track the new values.
These dictionaries store the values that the data source control can utilize. Below
is the method to get the value from the editing control and add it to the
dictionary.
Listing 7
public override void ExtractValuesFromCell(IOrderedDictionary dictionary,
DataControlFieldCell cell, DataControlRowState rowState, bool includeReadOnly)
{
base.ExtractValuesFromCell(dictionary, cell, rowState, includeReadOnly);
string value = null;
if (cell.Controls.Count > 0)
value = this.GetEditControlValue(cell);
string dataField = this.GetDataItemFieldName();
if (dictionary.Contains(dataField))
dictionary[dataField] = value;
else
dictionary.Add(dataField, value);
}
If you look at the code sample, the code to add/insert the
item in the dictionary has been extracted to an AddDictionaryEntry method.