I have a repeater that displays search results - inside the ItemTemplate I have a UserControl that renders my products.
Within my page I have an ItemCommand event that handles the PostBack by way of button click.
This all works fine when I have a hard code UserControl.
I want to be able to swap out the UserControl dynamically as I want to offer a choice of list and grid style results. This works OK but now my postback isn't functioning at all.
I am currently dynamically loading the UserControl within the ItemDataBound event for the repeater.
EDIT : By rebinding the repeater control on postback it seems to fix the postback to a blank page, but my ItemCommand event seems to be struggling to find the controls within the dynamic UserControl. I have no idea if the placeholder bit is required it was
just a punt :
Protected Sub rptMicro_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptMicro.ItemCommand
If e.CommandName = "BasketAdd" Then
Dim ph As PlaceHolder
Dim uc As UserControl
Dim txtQty As TextBox
ph = CType(e.Item.FindControl("phList"), PlaceHolder)
Select Case intDisplay
Case 2
uc = CType(ph.FindControl("ProductListingGrid"), UserControl)
Case Else
uc = CType(ph.FindControl("ProductListing"), UserControl)
End Select
txtQty = CType(uc.FindControl("txtBasketQty"), TextBox)
Dim clsbasket As New clsBasket
clsbasket.InsertItem(e.CommandArgument, Integer.Parse(txtQty.Text))
clsbasket = Nothing
Response.Redirect("Basket.aspx?MODE=1")
End If
End Sub
Your problem stems from the fact that dynamically-added controls must always be recreated on every postback. Otherwise their ViewState is not recuperated, and ViewState is the mechanism in charge of generating events like the click of a button.
The ItemDataBound event is not a good place to add dynamic controls because it only runs in response of data binding (as in calling DataBind()), but DataBind() destroys the internal control hierarchy and the corresponding ViewState, effectively killing all
user input and pending events from those internal controls, so it really isn't an option.
To be honest I don't think I have a solution to this. I can only suggest that you try the
ItemCreated event. See if that event runs even for postbacks without the need to data bind again.
Make sure that you load the repeater early enough in the page lifecycle. Page_Load is too late. It actually occurs after OnLoad. Onload is good, OnPreLoad often works better but is only available in the page lifecycle and not a control.
The controls have to be created early enough so that there is something there to catch the postback events. If you create it too late, it may look like it worked, but actually happened after postback so there is nothing there to catch an itemcommand at that
time. Creating the controls early enough should do the trick.
Don't forget to mark useful responses as Answer if they helped you towards a solution.
Make sure that you load the repeater early enough in the page lifecycle. Page_Load is too late. It actually occurs after OnLoad. Onload is good, OnPreLoad often works better but is only available in the page lifecycle and not a control.
The controls have to be created early enough so that there is something there to catch the postback events. If you create it too late, it may look like it worked, but actually happened after postback so there is nothing there to catch an itemcommand at that
time. Creating the controls early enough should do the trick.
That's actually a myth. Many people believe this but it is entirely untrue. You may add controls dynamically at almost any point in the page's lifecycle. The instant the control is added to the page it plays catch-up with the page lifecycle. It is written
in MSDN here. You can add dynamic controls in PreRender if you need/want.
Marked as answer by Amy Peng - MSFT on Mar 01, 2013 01:18 AM
You've always been able to add them anywhere, and the events of the lifecycle play catch up, but, as has been mentioned here way too many times for years is the discussion of when is best to add the control to have it created in time to receive postback
data. Having been working with .Net since 1.0, I'm well aware of the issues of timing in webforms in order to ensure the pieces are created in time to exist to receive postback to raise user-defined events.
Don't forget to mark useful responses as Answer if they helped you towards a solution.
Marked as answer by Amy Peng - MSFT on Mar 01, 2013 01:18 AM
discussion of when is best to add the control to have it created in time to receive postback data
There's no discussion. The control always receive it as long as added on PreRender or earlier. That's what I'm saying. This is a myth. It is 100% NOT true.
chilluk
Member
223 Points
226 Posts
Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 21, 2013 04:17 PM|LINK
I have a repeater that displays search results - inside the ItemTemplate I have a UserControl that renders my products.
Within my page I have an ItemCommand event that handles the PostBack by way of button click.
This all works fine when I have a hard code UserControl.
I want to be able to swap out the UserControl dynamically as I want to offer a choice of list and grid style results. This works OK but now my postback isn't functioning at all.
I am currently dynamically loading the UserControl within the ItemDataBound event for the repeater.
EDIT : By rebinding the repeater control on postback it seems to fix the postback to a blank page, but my ItemCommand event seems to be struggling to find the controls within the dynamic UserControl. I have no idea if the placeholder bit is required it was just a punt :
Protected Sub rptMicro_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.RepeaterCommandEventArgs) Handles rptMicro.ItemCommand If e.CommandName = "BasketAdd" Then Dim ph As PlaceHolder Dim uc As UserControl Dim txtQty As TextBox ph = CType(e.Item.FindControl("phList"), PlaceHolder) Select Case intDisplay Case 2 uc = CType(ph.FindControl("ProductListingGrid"), UserControl) Case Else uc = CType(ph.FindControl("ProductListing"), UserControl) End Select txtQty = CType(uc.FindControl("txtBasketQty"), TextBox) Dim clsbasket As New clsBasket clsbasket.InsertItem(e.CommandArgument, Integer.Parse(txtQty.Text)) clsbasket = Nothing Response.Redirect("Basket.aspx?MODE=1") End If End SubwebJose
Member
730 Points
186 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 21, 2013 05:35 PM|LINK
Your problem stems from the fact that dynamically-added controls must always be recreated on every postback. Otherwise their ViewState is not recuperated, and ViewState is the mechanism in charge of generating events like the click of a button.
The ItemDataBound event is not a good place to add dynamic controls because it only runs in response of data binding (as in calling DataBind()), but DataBind() destroys the internal control hierarchy and the corresponding ViewState, effectively killing all user input and pending events from those internal controls, so it really isn't an option.
To be honest I don't think I have a solution to this. I can only suggest that you try the ItemCreated event. See if that event runs even for postbacks without the need to data bind again.
markfitzme
All-Star
15343 Points
2358 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 22, 2013 02:02 AM|LINK
Make sure that you load the repeater early enough in the page lifecycle. Page_Load is too late. It actually occurs after OnLoad. Onload is good, OnPreLoad often works better but is only available in the page lifecycle and not a control.
The controls have to be created early enough so that there is something there to catch the postback events. If you create it too late, it may look like it worked, but actually happened after postback so there is nothing there to catch an itemcommand at that time. Creating the controls early enough should do the trick.
webJose
Member
730 Points
186 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 22, 2013 03:13 AM|LINK
That's actually a myth. Many people believe this but it is entirely untrue. You may add controls dynamically at almost any point in the page's lifecycle. The instant the control is added to the page it plays catch-up with the page lifecycle. It is written in MSDN here. You can add dynamic controls in PreRender if you need/want.
markfitzme
All-Star
15343 Points
2358 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 22, 2013 03:47 AM|LINK
You've always been able to add them anywhere, and the events of the lifecycle play catch up, but, as has been mentioned here way too many times for years is the discussion of when is best to add the control to have it created in time to receive postback data. Having been working with .Net since 1.0, I'm well aware of the issues of timing in webforms in order to ensure the pieces are created in time to exist to receive postback to raise user-defined events.
chilluk
Member
223 Points
226 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 22, 2013 07:41 AM|LINK
Thanks for all the replies.
The line it's stalling on now is :
txtQty = CType(uc.FindControl("txtBasketQty"), TextBox)Does that suggest it's finding the user control that contains that control, but not the control itself?
webJose
Member
730 Points
186 Posts
Re: Loading UserControl Dynamically inside Repeater has broken PostBack
Feb 22, 2013 01:02 PM|LINK
There's no discussion. The control always receive it as long as added on PreRender or earlier. That's what I'm saying. This is a myth. It is 100% NOT true.