This is a migrated thread and some comments may be shown as answers.

Checkbox Grid Column - Value won't update

1 Answer 478 Views
Grid
This is a migrated thread and some comments may be shown as answers.
J
Top achievements
Rank 1
J asked on 26 Mar 2013, 04:02 PM
I have a column defined as:
<telerik:GridCheckBoxColumn ConvertEmptyStringToNull="False"
    FilterControlAltText="Filter checked column" SortExpression="Checked"
    UniqueName="Checked" DataField="Checked" HeaderText="Remove" ToolTip="Check this box to remove this item from your cart" DataType="System.Boolean">
    <HeaderStyle Wrap="False" HorizontalAlign="Left" Width="80px" CssClass="grid-header grid-header-first" />
    <ItemStyle HorizontalAlign="Center" Width="100%" VerticalAlign="Top" />
</telerik:GridCheckBoxColumn>

This column is the only edit-able field in the grid, the rest are bound columns marked as ReadOnly.  The grid always has all rows in edit mode using the following:
protected void grdItems_PreRender(object sender, EventArgs e)
{
    try
    {
        foreach (GridDataItem colGridField in grdItems.MasterTableView.Items)
            colGridField.Edit = true;
 
        grdItems.Rebind();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
}

I have a button which needs to look at each row's check box and remove any items that are checked (perfromed by the CleanUpData method).  The button's click handler is:
protected void btnUpdateCart_Click(object sender, EventArgs e)
{
    try
    {
        //grdItems.MasterTableView.Items[grdItems.MasterTableView.Items.Count - 1].FireCommandEvent("UpdateAll", string.Empty);
        grdItems.EditItems[0].FireCommandEvent("UpdateEdited", string.Empty);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
}

Here is the UpdateCommand event from the grid's code:
protected void grdItems_UpdateCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
    GridEditableItem itmUpdatedRow = null;
    Hashtable tblUpdatedValues = null;
 
    try
    {
        //Get the details of the item that needs to be updated
        itmUpdatedRow = e.Item as GridEditableItem;
        tblUpdatedValues = new Hashtable();
 
        //Parse out the updated data
        e.Item.OwnerTableView.ExtractValuesFromItem(tblUpdatedValues, itmUpdatedRow);
 
        //Update the underlying data table with the updated information (THIS IS ALWAYS FALSE REGARDLESS OF CHECKED STATUS)
        _propsSettings.Records.Rows[e.Item.DataSetIndex]["Checked"] = tblUpdatedValues["Checked"].ToString().GetBoolean();
 
        grdItems.Rebind();
 
        CleanUpData();
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
    finally
    {
        SaveControlState();
 
        //Clean up
        if (tblUpdatedValues != null)
        {
            tblUpdatedValues.Clear();
            tblUpdatedValues = null;
        }
    }
}

Here, the line that uses 'tblUpdatedValues["Checked"]' is ALWAYS False regardless of the check boxes status.  I had a similar issue before using a dropdown column but I got around that by changing it's editor to a standard ASP.NET dropdown.  I tried doing the same here but I got the same results.  The value of the Checked column is ALWAYS False no matter what I do.

This method shouldn't matter but I'm including it for completeness' sake (this code would only have an impact if at least 1 checkbox is detected as checked):
/// <summary>
/// Cleans up the Items grid data to make sure any invalid rows are removed.
/// </summary>
private void CleanUpData()
{
    try
    {
        _propsSettings.TotalPrice = 0;
        _propsSettings.ShippingTotal = 0;
        _propsSettings.LateFees = 0;
 
        if (_propsSettings.Records.Rows.Count > 0)
        {
            //Start at the end so that removing rows won't cause the index to be incorrect
            for (int iItems = (_propsSettings.Records.Rows.Count - 1); iItems > -1; iItems--)
            {
                try
                {
                    //Item was selected for removal
                    if (_propsSettings.Records.Rows[iItems][0].ToString().GetBoolean())
                    {
                        //Delete the line item database record and remove it from the data set
                    }
                    else
                    {
                        //Track the calculated totals
                        _propsSettings.ShippingTotal += _propsSettings.Records.Rows[iItems]["ShippingPrice"].ToString().GetNumber();
                        _propsSettings.TotalPrice += ((_propsSettings.Records.Rows[iItems]["OriginalPrice"].ToString().GetNumber() * _propsSettings.Records.Rows[iItems]["Quantity"].ToString().GetNumber()) + _propsSettings.Records.Rows[iItems]["ShippingPrice"].ToString().GetNumber());
 
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print("Error: " + ex.ToString());
                }
            }
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
    finally
    {
        SaveControlState();
 
        UpdateCartTotals();
        grdItems.Rebind();
    }
}


I've searched the forums, read the help articles, looked at the demos, but cannot figure out what is wrong.  Any ideas?

1 Answer, 1 is accepted

Sort by
0
J
Top achievements
Rank 1
answered on 26 Mar 2013, 04:56 PM
And of course, right after I post this I find this page (http://www.telerik.com/help/aspnet-ajax/grid-delete-items-depending-on-checkbox-state.html) which describes exactly what I want to do and now all is working.  I don't do it quite the exact same way but by using the template column and listening to the CheckedChanged event I was able to update my underlying data source with the value and then everything worked.  Just in case anyone else runs into this, here's the relevant code.

The code below may contain some extra events and pieces of data that seem unused but they are used, I've removed some of the code to better highlight the relevant pieces.

Column definition:
<telerik:GridTemplateColumn HeaderText="Remove" SortExpression="Checked" UniqueName="Checked"
    DataField="Checked" FilterControlAltText="Filter Checked column" ColumnEditorID="cmbGridEdit_Checked"
    ShowSortIcon="False">
    <ItemTemplate>
        <asp:CheckBox ID="chkRemoveItem" runat="server" AutoPostBack="True" OnCheckedChanged="chkRemoveItem_CheckChanged" />
    </ItemTemplate>
    <HeaderStyle Wrap="False" HorizontalAlign="Left" Width="80px" CssClass="grid-header grid-header-first" />
    <ItemStyle HorizontalAlign="Center" Width="100%" VerticalAlign="Top" />
</telerik:GridTemplateColumn>

Checkbox event handler:
protected void chkRemoveItem_CheckChanged(object sender, System.EventArgs e)
{
    CheckBox chkRemoveRow = null;
    GridDataItem itmRowToUpdate = null;
 
    try
    {
        chkRemoveRow = (CheckBox)sender; //The row's checkbox
        itmRowToUpdate = (GridDataItem)chkRemoveRow.NamingContainer; //The actual grid row
 
        //Update the underlying data source
        _propsSettings.Records.Rows[itmRowToUpdate.DataSetIndex]["Checked"] = chkRemoveRow.Checked;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
    finally
    {
        SaveControlState();
    }
}

ItemDataBound event for the grid:
protected void grdItems_ItemDataBound(object sender, GridItemEventArgs e)
{
    Control ctrlFieldEditor = null;
 
    try
    {
        //Some controls don't load the values into the custom editor's automatically so force the values through
        if (e.Item.IsInEditMode)
        {
            ctrlFieldEditor = ((GridEditableItem)e.Item)["Checked"].Controls[1];
 
            if ((ctrlFieldEditor != null) && (ctrlFieldEditor is CheckBox))
                ((CheckBox)ctrlFieldEditor).Checked = ((DataRowView)e.Item.DataItem)[0].ToString().GetBoolean();
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
}

The UpdateCommand event for the grid:
protected void grdItems_UpdateCommand(object sender, Telerik.Web.UI.GridCommandEventArgs e)
{
    GridEditableItem itmUpdatedRow = null;
 
    try
    {
        //Get the details of the item that needs to be updated
        itmUpdatedRow = e.Item as GridEditableItem;

        //Update the underlying data table with the updated information
        _propsSettings.Records.Rows[e.Item.DataSetIndex]["Checked"] = ((CheckBox)itmUpdatedRow.FindControl("chkRemoveItem")).Checked;
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
    finally
    {
        CleanUpData();

        itmUpdatedRow = null;
    }
}

The CleanUpData method that will actually perform the database record deleting and grid updating:
/// <summary>
/// Cleans up the Items grid data to make sure any invalid rows are removed.
/// </summary>
private void CleanUpData()
{
    try
    {
        _propsSettings.TotalPrice = 0;
        _propsSettings.ShippingTotal = 0;
        _propsSettings.LateFees = 0;
 
        if (_propsSettings.Records.Rows.Count > 0)
        {
            //Start at the end so that removing rows won't cause the index to be incorrect
            for (int iItems = (_propsSettings.Records.Rows.Count - 1); iItems > -1; iItems--)
            {
                try
                {
                    //Item was selected for removal
                    if (_propsSettings.Records.Rows[iItems]["Checked"].ToString().GetBoolean())
                    {
                        //Delete the line item database record
                        if (DeleteOrderLineItem(_propsSettings.Records.Rows[iItems]["UniqueID"].ToString()))
                            _propsSettings.Records.Rows.RemoveAt(iItems);
                    }
                    else
                    {
                        //Track the calculated totals
                        _propsSettings.ShippingTotal += _propsSettings.Records.Rows[iItems]["ShippingPrice"].ToString().GetNumber();
                        _propsSettings.TotalPrice += ((_propsSettings.Records.Rows[iItems]["OriginalPrice"].ToString().GetNumber() * _propsSettings.Records.Rows[iItems]["Quantity"].ToString().GetNumber()) + _propsSettings.Records.Rows[iItems]["ShippingPrice"].ToString().GetNumber());
 
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print("Error: " + ex.ToString());
                }
            }
 
            //If there are no more line items, get rid of the order header records
            if ((_propsSettings.Records.Rows.Count == 0) && (_propsSettings.OrderIDs.Count > 0))
            {
                for (int iOrders = (_propsSettings.OrderIDs.Count - 1); iOrders > -1; iOrders--)
                {
                    if (DeleteOrderHeader(_propsSettings.OrderIDs[iOrders]))
                        _propsSettings.OrderIDs.RemoveAt(iOrders);
                }
            }
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.Print("Error: " + ex.ToString());
        Exceptions.ProcessModuleLoadException(this, ex);
    }
    finally
    {
        SaveControlState();
 
        UpdateCartTotals();
        grdItems.Rebind();
    }
}


Hope that helps anyone in a similar situation.
Tags
Grid
Asked by
J
Top achievements
Rank 1
Answers by
J
Top achievements
Rank 1
Share this question
or