True DBGrid for WinForms | ComponentOne
In This Topic
    UnBound Columns
    In This Topic

    Normally, True DBGrid for WinForms automatically displays data from bound database fields. However, you may need to augment the set of fields present in your layouts with columns derived from database fields, or columns that are unrelated (or only loosely related) to database information. For example, if your database contains a Balance field, you may instead want to display two columns, Credit and Debit, to show positive and negative numbers separately. Or, you may want to look up data in another database, or convert field data to some other form, such as mapping numeric codes to textual descriptions.

    To accomplish such tasks you can use unbound columns. The term unbound column refers to a column that is part of a bound grid, but is not tied directly to a database field.

    Columns that do not have the DataField property set (that is, the DataField property is equal to an empty string), but do have the column Caption property set are considered unbound columns. The grid will request data for these columns through the UnboundColumnFetch event.

    Columns with their DataField property set will be bound, if the DataField property is the same as one of the fields of the Data Source.

    Columns with their DataField property set to a value that is not in the DataSet are ignored for the purposes of fetching data. Similarly, columns that have no value for both the DataField and Caption properties set are also ignored.

    Creating Unbound Columns

    The first step in using an unbound column is creating the column itself. This may be done in the designer by adding a column through the C1TrueDBGrid Designer. In code, unbound columns may be added using the Insert method of the C1DataColumnCollection. The column must be given a name by setting its Caption property. In the designer, this is done using the C1TrueDBGrid Designer. In code, the Caption property of the appropriate C1DataColumn object is set. C1DataColumn objects that are added to the C1DataColumnCollection cause a corresponding C1DisplayColumn to be added to the C1DisplayColumnCollection for all splits. The default visible property of the newly added C1DisplayColumn will be False.

    When attempting to insert an unbound column in code, use the Rebind method to ensure that the column appears at the desired position within the grid:

    When the grid needs to display the value of an unbound column, it fires the UnboundColumnFetch event. This event supplies the user with a row and column index as the means of identifying the grid cell being requested. The Value property to the event is of type Object that by default is Null, but can be changed to any desired value, and will be used to fill the contents of the cell specified by the given row and column index.

    C#
    Copy Code
    C1.Win.C1TrueDBGrid.C1DataColumn Col = new C1.Win.C1TrueDBGrid.C1DataColumn();
    C1.Win.C1TrueDBGrid.C1DisplayColumn dc;
    c1TrueDBGrid1.Columns.Insert(0, Col);
    Col.Caption = "Unbound";
    dc = c1TrueDBGrid1.Splits[0].DisplayColumns["Unbound"];         
    // Move the newly added column to leftmost position in the grid.
    c1TrueDBGrid1.Splits[0].DisplayColumns.RemoveAt(0);
    c1TrueDBGrid1.Splits[0].DisplayColumns.Insert(0, dc);
    dc.Visible = true;
    c1TrueDBGrid1.Rebind(true);
    

    Implementing Multiple Unbound Columns

    So far, our examples have demonstrated the UnboundColumnFetch event using only a single unbound column but more than one unbound column can be used. Since the UnboundColumnFetch is fired for each unbound column of each row, only one column value may be set at a time, and each column must be identified for the value to be properly determined. The second UnboundColumnFetch property, Column, is used to identify the column of the grid for which the value is required.

    C#
    Copy Code
            System.Data.DataTable dtCopy = new System.Data.DataTable();                
    private void Form1_Load(object sender, System.EventArgs e)
    {
        this.oleDbConnection1.ConnectionString = GetModifiedConnectionString(this.oleDbConnection1.ConnectionString);
        oleDbDataAdapter1.Fill(dsContacts1);
        dtCopy = this.dsContacts1.Tables[0].Copy();
    }
    
    private void c1TrueDBGrid1_UnboundColumnFetch(object sender, C1.Win.C1TrueDBGrid.UnboundColumnFetchEventArgs e)
    {
        if(e.Col == 8 && e.Row < dtCopy.Rows.Count)
        {
            e.Value = dtCopy.Rows[e.Row].ItemArray.GetValue(0).ToString() + " " + dtCopy.Rows[e.Row].ItemArray.GetValue(1).ToString();
        }
    }
    

    Updating Unbound Columns

    In most cases, unbound columns will be read-only, as the values are derived from other data in the grid. In these cases, set the Locked property of the column's style to True.

    If Locked is False and updates are allowed, the user can edit the values of an unbound column. If editing of an unbound column occurs, the row will be marked as dirty (a pencil icon will be shown in the record selector column) and the update sequence will be performed as usual. However, the grid does not know what to do with the modified data, since there is no database field in which to store it. In this situation the UnboundColumnUpdated event will be raised. 

    The BeforeUpdate event can be used to cancel the update operation. Therefore, if the unbound column is to be used in cooperation with another database, the update of the unbound column should be performed in BeforeUpdate. If the operation fails, then the event should be canceled. However, if the operation succeeds, then the bound update should be allowed to proceed. The bound update may then fail; hence any database actions associated with unbound columns would best be handled on a transactional basis.

    If the bound update succeeds, the AfterUpdate event is fired, and the unbound column transaction should be committed. If the bound update fails, the unbound column transaction should be rolled back within .NET's trappable error handler, depending on how the update was initiated. If transactions are not available, then store the original unbound column values prior to the update, then perform another update to restore these values should the bound update fail.

    Editing Unbound Columns

    Another technique for updating an unbound column is to use the AfterColUpdate event to adjust the value of other (bound) columns. For example, imagine a pair of columns for Debit and Credit, as shown in this portion of a grid display:

    Assume that there is no database field for these, but that they are unbound columns that derive their value from a single Balance column, which is either positive or negative. From the user's perspective, it would be desirable to edit these values directly. From your perspective, it would be desirable to have the grid update the dependent Balance column automatically.

    True DBGrid for WinForms makes such tasks easy. The following code would be put in the grid's AfterColUpdate event to cause either column to change the Balance column when updated:

    C#
    Copy Code
    private void C1TrueDBGrid1_AfterColUpdate(object sender, C1.Win.C1TrueDBGrid.ColEventArgs e)
    {
        int row = this.c1TrueDBGrid1.Row;
        this.c1TrueDBGrid1[row, "Balance"] = e.Column.DataColumn.Value;                
    }
    

    Notice that, when updating these columns, the code actually changes the value of the Balance column, which is both bound and invisible.