You have to create dynamic controls in Page_Init. You have to create them the same way for all requests. That means, run the same code to create the control and add it to the controls collection every time the page is loaded regardless of IsPostBack or not.
Also, I would suggest that you save the instance of the dynamic control to a private member variable so you don't have to call FindControl
as that is potentially expensive.
Since it looks like you have a list of products somewhere, here is an example using a dictionary to store the checkboxes:
public partial class _Default : Page
{
private Dictionary<Int32,CheckBox> _myDynamicCheckBoxes;
protected override void OnInit(EventArgs e)
{
_myDynamicCheckBoxes = new Dictionary<Int32,CheckBox>();
foreach (var product in _listOfProducts)
{
var chkBox = new CheckBox {ID = "CheckBox" + product.ID.ToString()};
_myDynamicCheckBoxes.Add(product.ID,chkBox);
//add the checkbox to a Controls collection
}
}
}
Then somewhere else in your code, when you have a product and you want to find the checkbox associated you can use: var aCheckBox = _myDynamicCheckBoxes[product.ID];