© 2004 Microsoft Corporation. All rights reserved.
Figure 2 Taking Expressions into Account
// dbf    is the DataBoundField class for the currently processed column
// dbdr   is the DBDataRecord structure (data reader) with the values 
//        for the row
// i      is the index of the currently processed column
// buf    is the string that will contain the actual text to display for 
//        the column

if (!dbdr.IsDBNull(i) && dbf.BoundField != "")        
{
    // Is there an expression to take into account? 
    String fields = dbf.DataTextField;
    if (dbf.Expression != "")
        fields = dbf.Expression + " AS " + dbf.DataTextField;

    // Show the bound text instead of the current value
    String strCmd = "SELECT {0} FROM {1} WHERE {2} = '{3}'";
    strCmd = String.Format(strCmd, fields, dbf.TableName, dbf.Data
                           ValueField, dbdr[i].ToString());
    
    SqlConnection conn = new SqlConnection(ConnectionString);
    SqlCommand cmd = new SqlCommand(strCmd, conn);
    conn.Open();
    buf = cmd.ExecuteScalar().ToString();
    conn.Close();

    // Further formatting needed?
    if (dbf.FormatText != "")
        buf = String.Format(dbf.FormatText, buf);
}
Figure 4 Tri-state Control
if (dbf.CtlType == ControlType.TriStateBox) 
{
    // Create the radiobutton list control as appropriate
    RadioButtonList radio = new RadioButtonList();
    radio.RepeatDirection = RepeatDirection.Horizontal;
    radio.RepeatLayout = RepeatLayout.Flow;

    radio.ID = strFieldName;
    radio.ForeColor = DataForeColor;
    radio.BackColor = DataBackColor;
    if (strFieldName.ToLower() == SearchKeyField.ToLower())
        radio.BackColor = DataKeyBackColor;
    radio.Font.Size = grid.Font.Size;
    radio.Font.Name = grid.Font.Name;  
    radio.Width = Unit.Percentage(100);

    // Add items to the radio button list
    ListItem li;
    li = new ListItem(ConvertBooleanToString(false, dbf.BooleanText) +      
         "    ", "0");
    radio.Items.Add(li);
    li = new ListItem(ConvertBooleanToString(true, dbf.BooleanText) + 
         "    ", "1");
    radio.Items.Add(li);
    li = new ListItem(dbf.UndefinedText, "");
    radio.Items.Add(li);

    if (dbdr.IsDBNull(i))
        radio.SelectedIndex = 2;    // undefined
    else
        radio.SelectedIndex = (Convert.ToBoolean(dbdr[i]) ?1 :0);

    if (dbf.ReadOnly)
    {
        radio.BackColor = m_ReadOnlyColor;
        radio.Enabled = false;
    } 

    // Add the control to the cell
    cellColValue.Controls.Add(radio);
}
Figure 6 Delete Scripting
private void SetScriptForDeleteButton(DbDataRecord dbdr)
{
    // Prepare the data-bound text for deletion messages
    String js = "return confirm('{0}"; 
    js = String.Format(js, DeleteTextFormatString); 

    if (DeleteTextParams != null)
    {
        ArrayList a = (ArrayList) DeleteTextParams.Clone();
            
        // Expands the array of field names with actual values
        for(int i=0; i<DeleteTextParams.Count; i++) 
        {
            a[i] = dbdr[DeleteTextParams[i].ToString()];
        }

        js = String.Format(js, a.ToArray());
    }

    // Attach client script to the button
    m_btnDelete.Attributes["onclick"] = js;
}
Figure 8 Deleting an Employee

Figure 8 Deleting an Employee Figure 9 CurrentChanged Event Handler
public void CurrentChanged(Object sender, 
                           DataNavigatorChangedEventArgs e)
{
    // e.Position is a DataSet index
    // Let's translate this into a page-based number and move to the new 
    // page
    int pos = e.Position;
        
    // Page to jump to
    int nPageIndex = pos/grid.PageSize;
        
    // Index in the page
    int nRecordPos = pos - (nPageIndex*grid.PageSize);
        
    // Keep the grid in sync
    grid.CurrentPageIndex = nPageIndex;
    grid.SelectedIndex = nRecordPos;
    RefreshGrid();
}
Figure 10 Master Menu and Navigator

Figure 10 Master Menu and Navigator Figure 12 Customized View

Figure 12 Customized View Figure 13 DataNavigatorLayoutControl
public class DataNavigatorLayoutControl : UserControl
{
   // Provides the ASCX with the current record (both view and edit)
   public DbDataRecord Row;

   // Whether the record has to be processed as an update or an insert 
   // (edit only)
   public bool IsNewRecord;

   // Provides the ASCX with the container's unique ID (edit only, ASCX
   // shouldn't use it)
   private String m_containerUniqueID;
   public void SetContainerUniqueID(String uniqueId)
   {
      m_containerUniqueID = uniqueId;
   }

   // SqlDataNavigator calls this method to get the value for the 
   // specified field
   // By default, it returns the value of a ASP.NET control with the same   
   // ID as the field 
   // ASCX can override this to apply some pre-processing logic
   // Edit only
   public virtual object GetFieldValue(String field)
   {
      return GetControlValue(field);
   }

   // Return False if the field must be considered ReadOnly or Not 
   // Visible and subsequently does not participate in update operations
   // By default all fields are updateable
   public virtual bool IsUpdateable(String field)
   {
      return true;
   }

   ///////////////////////////////////////////////////////////////////
   /// Internal protected member to retrieve the persisted value 
   /// of a given control
   protected object GetControlValue(String ctlID)
   {
      // EditTemplate is constant because set by the SqlDataNavigator 
      // control
      String strCtlID = m_containerUniqueID + ":_ctl3:EditTemplate:" + 
      ctlID;
      return Page.Request.Form[strCtlID];
   }
}
Figure 14 Custom ASCX Code
Public Overrides Function IsUpdateable(field As String) As Boolean
    If field="Title" Or field="TitleOfCourtesy" Or _
        field="EmployeeId" Or field="BirthDate" Or _
        field="Photo" Or field="ReportsTo" Or field="PhotoPath" Then
        Return False
    End If
        
    Return MyBase.IsUpdateable(field)
End Function

    
Public Overrides Function GetFieldValue(field As String) As Object
    If field = "HireDate" Then
        Dim mm, dd, yy As String
        mm = CType(GetControlValue("theDateBox:Month"), String)
        dd = CType(GetControlValue("theDateBox:Day"), String)
        yy = CType(GetControlValue("theDateBox:Year"), String)
        If mm="" Or dd="" Or yy="" Then
            Return ""
        Else 
            Return String.Format("{0}-{1}-{2}", mm, dd, yy)
        End If
    Else
        Return MyBase.GetFieldValue(field)
    End If
End Function
Figure 15 Northwind Console

Figure 15 Northwind Console

Home
Topics
Issues
Columns
Downloads
Subscribe
Contact Us

MSDN Magazine