This has been driving me crazy for 2 days now - hope someone has seen this before.
I have this issue where the first click of a control within a repeater or grid view fa
I figured it out, but I don't understand why.
The original code was:
Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)
I changed it to make the table visible and add it to the placeholder before I set the datasource and bound it. Problem solved.
Me.tblAgreementContractors.Visible = True
Me.phDataPane.Controls.Add(Me.tblAgreementContractors)
Me.rpAgreementContractors.DataSource = dtContractors
Me.rpAgreementContractors.DataBind()
MikeW,
After hours and hours of fiddling with this, I found the root of your issue.
It has nothing particular to do with the repeater or the gridview.
It is simply a dynamic-controls-on-a-postback issue.
To solve your issue:
Amazingly, just one line is missing in your code.
Right when you load the control, assign something to its ID, like so:
UserControl uc = (UserControl)LoadControl(controlPath);
uc.ID = "mycontrol";
ph.Controls.Add(uc);
That way, when you postback, the page knows which control is which.
To explain this more easily, let's simplify the problem.
Here's a scenario of clicking a button twice in a row that dynamically creates another button:
ViewState
to tell the page there's a dynamic control. Like you did, we can memorize the control's path, or the name of its class. Page_Load
, we look at the ViewState
to see that there is a control we're trying to retain, so we load it right there (this is equivalent to your LoadUserControl()
function above). Page_Load
will load Button2 from the ViewState
. And the Click
event of Button1 will load ANOTHER Button2 instance, after clearing the placeholder. UniqueID
, and those two Button2s will have something like ctl02 and ctl03UniqueID
, which is sequentially generated. Click
doesn't fire.UniqueID
ctl02.UniqueID
of ctl02. So, how does assigning an ID make it work?
That way, each new control generated will have the same ID, so on the postback, it can find what it's looking for, whether it was generated in Page_Load
or on another button's Click
event.
Hope that explains why it works, but as far as you care, just assign it an ID and all will be good.
I thought it would be interesting to share the mechanism behind it and why that's the case. =)
I'm not sure about the rest of your code, but usually when I see a problem of "first action behaves different than subsequent actions" like this is because I placed something in the wrong side of the IsPostBack
section.
For example, I find myself binding when it's a postback, so my events don't work until the second postback, coz the first postback is when they were born, and the initial page load never did that part.
I think you're on the right track; make sure you're binding and wiring up your events at the right moment.