I'm currently reimplementing some functionality on one of our main websites at work. The page lists out literature defined in the backend database and dynamically outputs to the page with thumbnails.
To accomodate an ever increasing amount of litreature we decided to section the page using tabs. Our backend database holds products in a hierarchical tree of groups (litreature is just product from the DB's point of view) so it made sense to generate tabs on the page dynamically using sub-groups of a master litreature group.
ASP.NET 2.0 has a nice AJAX control tookit which is built on top of the ASP.NET AJAX framework (open-source too). I've used some of the other controls on other projects, but not the TabContainer and TabPanels.
Great I thought; create my UserControl, add a TabContainer and then populate the TabContainer from the code-behind as below:
Private Sub LoadTabs() Dim MyCatalogueGroups As New Groups MyCatalogueGroups = MyCatalogueGroups.GetChildGroups(Me.AppSettings.CatalogueGroup) Dim intCurrentTabIndex As Int32 Dim intDefaultTabIndex As Int32 For Each MyCatalogueGroup As Group In MyCatalogueGroups Dim MyTabPanel As TabPanel = New TabPanel MyTabPanel.HeaderText = MyCatalogueGroup.Description '.....panel contents code removed for brevity Me.ctlTabContainer.Tabs.Add(MyTabPanel) If Me.AppSettings.DefaultCatalogueSubGroup = MyCatalogueGroup.ID Then intDefaultTabIndex = intCurrentTabIndex End If intCurrentTabIndex += 1 Next Me.ctlTabContainer.ActiveTab = Me.ctlTabContainer.Tabs(intDefaultTabIndex) End Sub
Compile, Debug ... nothing. No error just nothing. Check the browser page source and there they are, but whats all this visible false stuff?
A bit of Googling later and I discover this is a bit of a mystery with the AJAX Tab controls. The solution is to call some JavaScript at the client so that the dynamically generated TabPanels can be made visible client-side. The sample code I found didn't work for me as I got client-side JavaScript errors as it couldn't ID the TabContainer control in the control collection. However it was a massive help and my working code is below:
<script type="text/javascript"> function pageLoad(){ // Required when adding TabPanels programmatically. var strTabContainerID = '<%= (FindControl("ctlTabContainer")).ClientID %>'; $get(strTabContainerID).style.visibility = "visible"; } </script>
The key here is line 4 where you specify the ID of your TabContainer control.
JavaScript isn't my thing and through a bit of trial and error I found that the best placement for the code snippet is actually adjacent to the TabContainer markup in your .ascx file.
function pageLoad(){ // Required when adding TabPanels programmatically. var strTabContainerID = '<%= (FindControl("ctlTabContainer")).ClientID %>'; $get(strTabContainerID).style.visibility = "visible"; } </script> <cc1:TabContainer ID="ctlTabContainer" runat="server" /> </asp:View>
I am using the TabContainer in a MultiView contol and I discovered that placing the JavaScript in the host page head creates client-side JavaScript errors when the View holding the TabContainer is not rendered back to the web browser (obvious really).
The only other thing to watch out for is creating your dynamic tabs as the page initialises rather than when the page loads, otherwise you will get this error if your page causes a postback event:
Specified Argument was out of the range of valid values Parameter Name: Index
This is discussed on the ASP.NET Forums and on 4GuysFromRolla.com, but essentially in ASP.NET 2.0 you can implement your own handler for the Page.Init event in the page or UserControl where you create your dynamic controls.
Protected Sub LoadDynamicControls(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init Me.LoadTabs() End Sub
I hope this helps somebody out.
No comments:
Post a Comment