Discussion on Development in Several Different Flavours

ASP.Net Dynamic Controls (Part 2)

September 1, 2006 | Tagged:

Note: While this technique works and is valid you are best to use the proper method which utilizes proper HTML form submission, is standards compliant and accessible.

In the last installment I brought to light the issues involved with using dynamic controls in an ASP.Net page. For the most part it was simply background on the topic so that this second more interesting part would make sense. The final point was that in certain situations you needed to know the result of an event before you could create the dynamic controls which is not possible to do without some sort of hack. The controls must be created, at the latest, in Page_Load but the page events fire after that, dilemma.

The essence of the solution is that all the controls place their values into the Request.Form collection which is available with or without the control existing in the Page. For example if you have a dropdownlist with an autopostback you can simply read the selected value from the Request.Form collection and make any changes to the dynamic controls before the actual event fires. This solves some issues but leaves quite a few still unsolved.

What if the control that caused the postback is a button? It doesn’t have a value that can be read in the Request.Form collection so we don’t know which button was clicked during the dynamic control creation phase. We will somehow have to change this fact. This first code example sets up a button that will give us an indication that it was clicked

<asp:HiddenField ID="hidAction" runat="server" />
<asp:Button ID="btnUpdate" Text="Update List"
  OnClientClick="document.getElementById('hidAction').value='btnUpdate';" runat="server" />

I really enjoy that Microsoft added the HiddenField control and the OnClientClick property in v2.0 of the framework it is very handy. I highly recommend to those using a previous version to upgrade. Soon v3.0 will be arriving and you are already seriously missing out on a much richer tool set. I believe that you can use a hidden label to simulate a HiddenField and the controls attribute collection to add the Javascript onclick. See the next code segment.

<asp:Label ID="lblAction" Visible="False" runat="server" />
<asp:Button ID="btnUpdate" Text="Update List" runat="server" />
<% btnUpdate.Attributes.Add("onclick",
  "document.getElementById('hidAction').value='btnUpdate';") %>

Now all we have to do is process the resulting information in the Page_Load event. You will see that I am leading with the next block of code. Pay special attention to the comments.

Sub Page_Load()
  If hidAction.Value = "btnUpdate" Then
    ' Process btnUpdate event
  End If
  hidAction.Value = ""
  ' Create dynamic controls
End Sub

So what was I leading to? Well you will note that I wrote “Process btnUpdate event” which essentially means do everything that you would normally do in Update_Click in this spot. Ok sure that’s no big deal, right? Actually it really is a big deal. If we can process events in the Page_Load event why have all those event handlers. Remember that I mentioned that if you don’t hook up an event handler before Page_Load it won’t work? Well what does that matter now? The dynamic control event handling can be done wherever I want now since I don’t even need to hook up the handler at all. One thing to note is that a Button control always postback even without a handler attached to it and that is why all this works.

Taking all that previous information in and knocking it around a bit we can come up with the notion that controls can be created at any time we want! We now do the event handling for those controls ourselves and only depend on ASP.Net’s default button postback behaviour. Let see the final picture.

Sub Page_Load()
  If hidAction.Value = "btnUpdate" Then
    ' Process btnUpdate event
  End If
  hidAction.Value = ""
  ' Create dynamic controls
End Sub
…
<asp:HiddenField ID="hidAction" runat="server" />
…
<% For i = 0 To 10
  Dim btn As Button = New Button()
  btn.ID = "btn" & i
  btn.OnClientClick = "document.getElementById('hidAction').value='btn" & i & "';"
  phControls.Controls.Add(btn)
End For %>
<asp:PlaceHolder ID="phControls" runat="server" />

Let me know how well this works for your application. I am using it quite extensively now to make my pages more interactive in a Javascript-y sort of way.

ASP.Net Dynamic Controls (Part 1) «
ASP.Net Dynamic Controls (Part 3) »
ASP.Net Dynamic Controls (Part 4) »

2 Comments »

RSS feed for comments on this post. TrackBack URI

Leave a comment