[Solved] Reference a CheckBox within a RadGrid inside a PlaceHolder

1 Answer 28 Views
Checkbox Grid
Wei
Top achievements
Rank 1
Iron
Iron
Wei asked on 25 Feb 2026, 07:15 AM

I am attempting to reference some CheckBoxes withing a RadGrid inside a PlaceHolder.

I have a field that I am retrieving called Block that contains a numerice value. Based on the value I am dynamically creating a number of CheckBoxes in a PlaceHolder equal to that value. I have a Button Click method that is trying to reference the CheckBoxes but it is not working correctly.

This line : Dim BlockCheckBox As CheckBox = DirectCast(phBlocksCheckBox.FindControl("BlockCheckBox_" & cbIndex), CheckBox) is not returning a value.

aspx
    <telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" AllowSorting="True" GridLines="None" AllowMultiRowSelection="True" AllowFilteringByColumn="True" EnableLinqExpressions="False">
        <MasterTableView AutoGenerateColumns="False">
            <PagerStyle AlwaysVisible="True"></PagerStyle>
            <Columns>
                <telerik:GridClientSelectColumn UniqueName="checkboxColumn1" HeaderTooltip="SELECT All" ShowSortIcon="False" ShowFilterIcon="False" Reorderable="False">
                    <HeaderStyle Width="30px" />
                <telerik:GridBoundColumn DataField="NumberOfBlocks" HeaderText="Block Count" UniqueName="NumberOfBlocks" AllowFiltering="False" Display="False">
                    <HeaderStyle Width="20px" />
                </telerik:GridBoundColumn>
                <telerik:GridTemplateColumn DataField="Block" HeaderText="Blocks" UniqueName="BlocksColumn" AllowFiltering="False">
                    <ItemTemplate>
                        <asp:PlaceHolder ID="phBlocksCheckBox" runat="server" />
                    </ItemTemplate>
                </telerik:GridTemplateColumn>
            </Columns>
        </MasterTableView>
        <ClientSettings AllowColumnsReorder="True" AllowDragToGroup="True" ReorderColumnsOnClient="True">
            <Scrolling UseStaticHeaders="True" />
            <Selecting AllowRowSelect="True" />
            <ClientEvents OnRowSelected="RowSelected" OnRowDeselected="RowDeselected"></ClientEvents>
        </ClientSettings>
    </telerik:RadGrid>


vb
    Protected Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles GenerateCassetteLabelsButton.Click
        Dim NumberOfBlocks As Integer = 0

        For Each item As GridDataItem In RadGrid1.SelectedItems
            NumberOfBlocks = CInt(item("NumberOfBlocks").Text)

            Dim phBlocksCheckBox As PlaceHolder = DirectCast(item.FindControl("phBlocksCheckBox"), PlaceHolder)
            If phBlocksCheckBox IsNot Nothing Then
HttpContext.Current.Response.Write("phBlocksCheckBox IsNot Nothing<br><br>")
                For cbIndex As Integer = 1 To NumberOfBlocks
HttpContext.Current.Response.Write("-BlockCheckBoxID : " & "BlockCheckBox_" & cbIndex & "<br><br>")
                    Dim BlockCheckBox As CheckBox = DirectCast(phBlocksCheckBox.FindControl("BlockCheckBox_" & cbIndex), CheckBox)

                    If BlockCheckBox IsNot Nothing Then
HttpContext.Current.Response.Write("BlockCheckBox IsNot Nothing<br><br>")
                        'Do something with BlockCheckBox.Text
HttpContext.Current.Response.Write("-Block : " & BlockCheckBox.Text & "<br><br>")
                    End If
                Next
            End If
        Next

        RadGrid1.Rebind()
    End Sub

    Protected Sub RadGrid1_ItemDataBound(sender As Object, e As GridItemEventArgs) Handles RadGrid1.ItemDataBound
        'Ensure we are dealing with a data item (not header, footer, etc.)
        If TypeOf e.Item Is GridDataItem Then
            Dim item As GridDataItem = DirectCast(e.Item, GridDataItem)

            'Find the placeholder control defined in the ItemTemplate
            Dim phBlocksCheckBox As PlaceHolder = CType(item.FindControl("phBlocksCheckBox"), PlaceHolder)

            If phBlocksCheckBox IsNot Nothing Then
                Dim NumberOfBlocks As Integer = DataBinder.Eval(item.DataItem, "NumberOfBlocks")

                'Dynamically create and add checkboxes
                If NumberOfBlocks > 0 Then
                    For BlockIndex As Integer = 0 To NumberOfBlocks - 1
                        Dim BlockCheckBox As New CheckBox()
                        BlockCheckBox.ID = "BlockCheckBox_" & (BlockIndex + 1).ToString()
                        BlockCheckBox.Text = (BlockIndex + 1).ToString()
                        BlockCheckBox.Checked = True
                        phBlocksCheckBox.Controls.Add(BlockCheckBox)
                        phBlocksCheckBox.Controls.Add(New LiteralControl("    "))
                    Next
                End If
            End If
        End If
    End Sub

 

1 Answer, 1 is accepted

Sort by
0
Vasko
Telerik team
answered on 02 Mar 2026, 06:37 AM

Hi Wei,

Thank you for the provided code snippet.

The issue happens because in ItemCreated the DataItem property is not available during PostBack, so DataBinder.Eval(item.DataItem, "NumberOfBlocks") returns null and no CheckBox controls are created. Since dynamic controls must be recreated on every postback before ViewState is restored, failing to rebuild them results in the PlaceHolder having zero controls when the button click executes.

Using DataKeyNames with GetDataKeyValue or reading the value from the Grid cell ensures the block count is available during ItemCreated. Once the controls are consistently recreated, they will exist in the control tree and can be accessed in Button_Click.

Below you can find the adjusted code snippet:

<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" OnNeedDataSource="RadGrid1_NeedDataSource" OnItemCreated="RadGrid1_ItemCreated">
    <MasterTableView AutoGenerateColumns="False" DataKeyNames="NumberOfBlocks">
        <Columns>
            <telerik:GridClientSelectColumn UniqueName="checkboxColumn1" />
            <telerik:GridBoundColumn
                HeaderText="Number of blocks"
                DataField="NumberOfBlocks"
                UniqueName="NumberOfBlocks"
                Display="true" />
            <telerik:GridTemplateColumn HeaderText="Blocks">
                <ItemTemplate>
                    <asp:PlaceHolder ID="phBlocksCheckBox" runat="server" />
                </ItemTemplate>
            </telerik:GridTemplateColumn>
        </Columns>
    </MasterTableView>
    <ClientSettings>
        <Selecting AllowRowSelect="true" />
    </ClientSettings>
</telerik:RadGrid>

<telerik:RadButton runat="server" ID="RadButton1" Text="Postback" AutoPostBack="true" OnClick="Button_Click" />
protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e)
{
    if (e.Item is GridDataItem item)
    {
        PlaceHolder phBlocksCheckBox = (PlaceHolder)item.FindControl("phBlocksCheckBox");

        if (phBlocksCheckBox != null)
        {
            int NumberOfBlocks = Convert.ToInt32(item.GetDataKeyValue("NumberOfBlocks"));

            if (NumberOfBlocks > 0)
            {
                for (int i = 1; i <= NumberOfBlocks; i++)
                {
                    CheckBox cb = new CheckBox();
                    cb.ID = "BlockCheckBox_" + i;
                    cb.Text = i.ToString();
                    cb.Checked = true;

                    phBlocksCheckBox.Controls.Add(cb);
                }
            }
        }
    }
}

protected void Button_Click(object sender, EventArgs e)
{
    foreach (GridDataItem item in RadGrid1.SelectedItems)
    {
        PlaceHolder  placeHolder = (PlaceHolder)item.FindControl("phBlocksCheckBox");

        if (placeHolder != null)
        {
            foreach (Control ctrl in placeHolder.Controls)
            {
                if (ctrl is CheckBox cb && cb.Checked)
                {
                    Response.Write("Checked: " + cb.Text + "<br>");
                }
            }
        }
    }
}

protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
    RadGrid1.DataSource = GetDummyData();
}

private DataTable GetDummyData()
{
    DataTable dt = new DataTable();

    dt.Columns.Add("ID", typeof(int));
    dt.Columns.Add("NumberOfBlocks", typeof(int));

    dt.Rows.Add(1, 3);
    dt.Rows.Add(2, 5);
    dt.Rows.Add(3, 2);
    dt.Rows.Add(4, 4);

    return dt;
}

    This ensures the CheckBoxes are always found.

    Regards,
    Vasko
    Progress Telerik

    Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources
    Wei
    Top achievements
    Rank 1
    Iron
    Iron
    commented on 04 Mar 2026, 12:12 AM

    Vasko,

    I converted your code to vb and I get error : 

    Multiple controls with the same ID 'BlockCheckBox_1' were found. FindControl requires that controls have unique IDs.

    vb Code :

        Protected Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles RadButton1.Click
            For Each item As GridDataItem In RadGrid1.SelectedItems
                Dim placeHolder As PlaceHolder = DirectCast(item.FindControl("phBlocksCheckBox"), PlaceHolder)

                If placeHolder IsNot Nothing Then
                    For Each ctrl As Control In placeHolder .Controls
                        If TypeOf ctrl Is CheckBox Then
                            Dim cb As CheckBox = DirectCast(ctrl, CheckBox)
                            If cb.Checked Then
                               Response.Write("Checked: " + cb.Text + "<br>")
                            End If
                        End If
                    Next
                End If
            Next
        End Sub

        Protected Sub RadGrid1_NeedDataSource(sender As Object, e As GridNeedDataSourceEventArgs) Handles RadGrid1.NeedDataSource
            RadGrid1.DataSource = GetDummyData()
        End Sub

        Private Function GetDummyData() As DataTable
            Dim dt As New DataTable()
            dt.Columns.Add("ID", GetType(Integer))
            dt.Columns.Add("NumberOfBlocks", GetType(Integer))

            dt.Rows.Add(1, 3)
            dt.Rows.Add(2, 5)
            dt.Rows.Add(3, 2)
            dt.Rows.Add(4, 4)
            Return dt
        End Function

        Protected Sub RadGrid1_ItemCreated(ByVal sender As Object, ByVal e As GridItemEventArgs) Handles RadGrid1.ItemCreated
            If TypeOf e.Item Is GridDataItem Then
                Dim phBlocksCheckBox As PlaceHolder = DirectCast(e.item.FindControl("phBlocksCheckBox"), PlaceHolder)

                If phBlocksCheckBox IsNot Nothing Then
                    Dim NumberOfBlocks As Integer = DataBinder.Eval(e.Item.DataItem, "NumberOfBlocks")

                    If NumberOfBlocks > 0 Then
                        For i As Integer = 1 To NumberOfBlocks
                            Dim cb As New CheckBox()
                            cb.ID = "BlockCheckBox_" & i
                            cb.Text = i.ToString()
                            cb.Checked = true

                            phBlocksCheckBox.Controls.Add(cb)
                        Next
                    End If
                End If
            End If
        End Sub

    Thanks,

    Wei

    Vasko
    Telerik team
    commented on 06 Mar 2026, 08:00 AM

    Hi Wei, 

    The error "Multiple controls with the same ID 'BlockCheckBox_1' were found. FindControl requires that controls have unique IDs." occurs because you are generating CheckBoxes with the same ID for each grid row. In ASP.NET, all controls in the same naming container must have unique IDs.

    To resolve this, you need to include a unique value from each data row (such as the row's primary key, "ID") in the CheckBox ID. This ensures that each CheckBox across the grid has a unique ID.

    Update the RadGrid1_ItemCreated method so the CheckBox ID includes the row's unique "ID" value:

    Protected Sub RadGrid1_ItemCreated(ByVal sender As Object, ByVal e As GridItemEventArgs)
        If TypeOf e.Item Is GridDataItem Then
            Dim item As GridDataItem = CType(e.Item, GridDataItem)
            Dim phBlocksCheckBox As PlaceHolder = DirectCast(item.FindControl("phBlocksCheckBox"), PlaceHolder)
    
            If phBlocksCheckBox IsNot Nothing Then
                Dim NumberOfBlocks As Integer = Convert.ToInt32(item.GetDataKeyValue("NumberOfBlocks"))
                Dim rowId As Integer = Convert.ToInt32(item.GetDataKeyValue("ID"))
    
                For i As Integer = 1 To NumberOfBlocks
                    Dim cb As New CheckBox()
                    cb.ID = "BlockCheckBox_" & rowId & "_" & i
                    cb.Text = i.ToString()
                    cb.Checked = True
                    phBlocksCheckBox.Controls.Add(cb)
                Next
            End If
        End If
    End Sub
    

    Make sure your grid uses DataKeyNames

    <MasterTableView AutoGenerateColumns="False" DataKeyNames="NumberOfBlocks, ID">

    When you need to access a specific CheckBox (e.g., in your Button_Click event), use the same ID pattern:

    Protected Sub Button_Click(sender As Object, e As EventArgs)
        For Each item As GridDataItem In RadGrid1.SelectedItems
            Dim placeHolder As PlaceHolder = DirectCast(item.FindControl("phBlocksCheckBox"), PlaceHolder)
    
            If placeHolder IsNot Nothing Then
                Dim NumberOfBlocks As Integer = Convert.ToInt32(item.GetDataKeyValue("NumberOfBlocks"))
                Dim rowId As Integer = Convert.ToInt32(item.GetDataKeyValue("ID"))
    
                For i As Integer = 1 To NumberOfBlocks
                    Dim cb As CheckBox = DirectCast(placeHolder.FindControl("BlockCheckBox_" & rowId & "_" & i), CheckBox)
                    If cb IsNot Nothing AndAlso cb.Checked Then
                        Response.Write("Checked: " & cb.Text & "<br>")
                    End If
                Next
            End If
        Next
    End Sub

    Regards,
    Vasko
    Progress Telerik

    Tags
    Checkbox Grid
    Asked by
    Wei
    Top achievements
    Rank 1
    Iron
    Iron
    Answers by
    Vasko
    Telerik team
    Share this question
    or