[RESOLVED] Programatically create (and remove) linkbuttons
Hello,
Here is my scenario. I have an asp.net Image map (needed this for postbacks), that is generated from xml, clicking a hotspot will postback and then either load a different image map or redirect to another page depending on what the postback value of the hotspot is.
Also every time a hotspot is clicked it needs to create a linkbutton to return to it, like a breadcrumb.
Here is my relevant code:
Code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
Dim ctrlTable As DataTable
ctrlTable = New DataTable
Dim ctrlID As DataColumn = New DataColumn("ctrlID")
Dim ctrlText As DataColumn = New DataColumn("ctrltext")
Dim ctrlCommand As DataColumn = New DataColumn("ctrlcommand")
Dim ctrlType As DataColumn = New DataColumn("ctrlType")
ctrlID.DataType = System.Type.GetType("System.String")
ctrltext.DataType = System.Type.GetType("System.String")
ctrlCommand.DataType = System.Type.GetType("System.String")
ctrlType.DataType = System.Type.GetType("System.String")
ctrlTable.Columns.Add(ctrlID)
ctrlTable.Columns.Add(ctrlText)
ctrlTable.Columns.Add(ctrlCommand)
ctrlTable.Columns.Add(ctrlType)
ViewState("ctrlTable") = ctrlTable
Else
If Not ViewState("ctrlTable") Is Nothing Then
Dim ctrlTable As DataTable
ctrlTable = ViewState("ctrlTable")
Dim x As Integer = 1
For Each dr As DataRow In ctrlTable.Rows
Select Case dr("ctrlType")
Case "link"
Dim lnkbutton As New LinkButton
lnkbutton.ID = dr("ctrlID")
lnkbutton.Text = dr("ctrltext")
lnkbutton.CommandArgument = dr("ctrlcommand")
lnkbutton.ToolTip = "Back"
AddHandler lnkbutton.Command, AddressOf mylinkEvent
plcBreadcrumb.Controls.Add(lnkbutton)
If Not x = ctrlTable.Rows.Count Or ctrlTable.Rows.Count = 1 Then
plcBreadcrumb.Controls.Add(New LiteralControl(" > "))
End If
Case "label"
Dim lnkLabel As New Label
lnkLabel.ID = dr("ctrlID")
lnkLabel.Text = dr("ctrltext")
plcBreadcrumb.Controls.Add(lnkLabel)
End Select
x += 1
Next
End If
End If
End Sub
'Called when hotpost is clicked
Protected Sub LoadImageMap(ByVal mapID As String)
Dim cArgument() As String = mapID.Split(";")
Dim ctrlTable As DataTable
ctrlTable = ViewState("ctrlTable")
'//Adds new linkbutton to collection, but only if isnt there already
Dim lnkDuplicate As Boolean = False
For Each dr As DataRow In ctrlTable.Rows
If dr("ctrlCommand") = mapID Then
lnkDuplicate = True
End If
Next
If lnkDuplicate = False Then
'//Item doesnt exist so user has gone forward
Dim row As DataRow = ctrlTable.NewRow()
row("ctrlID") = "lbl" & ctrlTable.Rows.Count
row("ctrlType") = "label"
row("ctrlText") = cArgument(1)
row("ctrlCommand") = cArgument(0) & ";" & cArgument(1)
ctrlTable.Rows.Add(row)
ViewState("ctrlTable") = ctrlTable
Dim lnkLabel As New Label
lnkLabel.ID = "lbl" & ctrlTable.Rows.Count
lnkLabel.Text = cArgument(1)
plcBreadcrumb.Controls.Add(lnkLabel)
End If
Dim map = New DataSet
map.ReadXml(MapPath("/xml/" & cArgument(0)))
If Not map Is Nothing AndAlso map.Tables(0).Rows.Count > 0 Then
For Each dr As DataRow In map.Tables(0).Rows
Stage3Map.ImageUrl = "~/images/" & dr("src")
Stage3Map.CssClass = "map"
Stage3Map.Width = CInt(dr("width"))
Stage3Map.Height = CInt(dr("height"))
Next
End If
Stage3Map.HotSpots.Clear()
If map.Tables(1).Rows.Count > 0 Then
For Each dr As DataRow In map.Tables(1).Rows
Select Case dr("shape")
Case "rect"
Dim hotSpot As New RectangleHotSpot
hotSpot.PostBackValue = dr("postback") & ";" & dr("title")
hotSpot.HotSpotMode = HotSpotMode.PostBack
hotSpot.AlternateText = dr("title")
Dim splitRect() As String = dr("coords").Split(",")
hotSpot.Top = splitRect(0)
hotSpot.Left = splitRect(1)
hotSpot.Right = splitRect(2)
hotSpot.Bottom = splitRect(3)
Stage3Map.HotSpots.Add(hotSpot)
Case "circle"
Dim hotSpot As New CircleHotSpot
hotSpot.PostBackValue = dr("postback") & ";" & dr("title")
hotSpot.HotSpotMode = HotSpotMode.PostBack
hotSpot.AlternateText = dr("title")
Dim splitCircle() As String = dr("coords").Split(",")
hotSpot.X = splitCircle(0)
hotSpot.Y = splitCircle(1)
hotSpot.Radius = splitCircle(2)
Stage3Map.HotSpots.Add(hotSpot)
Case "poly"
Dim hotSpot As New PolygonHotSpot()
hotSpot.PostBackValue = dr("postback") & ";" & dr("title")
hotSpot.HotSpotMode = HotSpotMode.PostBack
hotSpot.AlternateText = dr("title")
hotSpot.Coordinates = dr("coords")
Stage3Map.HotSpots.Add(hotSpot)
End Select
Next
End If
End Sub
Sub mylinkEvent(ByVal sender As Object, ByVal e As CommandEventArgs)
Dim ctrlTable As DataTable
ctrlTable = ViewState("ctrlTable")
Dim lnkDuplicate As Boolean = False
For Each dr As DataRow In ctrlTable.Rows
If dr("ctrlCommand") = e.CommandArgument Then
lnkDuplicate = True
End If
Next
If lnkDuplicate = True Then
'//Item exists already so user has gone backwards
ctrlTable.Rows(ctrlTable.Rows.Count - 1).Delete()
End If
LoadImageMap(e.CommandArgument)
End Sub
This is now only creating labels because I changed it to do this for now, what I really need to do is some.
The last sub is when one of the linkbuttons is clicked, it removes this linkbutton from the viewstate collection and then when page reloaded this shouldn't be re-created.
The issue is page load fires before the linkbutton sub, so my controls are re-created before I have had the chance to remove from the collection.
Can anyone offer some advice please?
Re: Programatically create (and remove) linkbuttons
It's difficult to visualise exactly what the page needs to do but I'll have a go....
Both imagemap and linkbutton postback which runs the breadcrumb code in the page load method. This works when the imagemap causes the postback but conflicts with the lickBtn.command method when it's links button that posts back.
So you need to determine what control caused the postback before running that code. There are a few articles about this here is one
http://ryanfarley.com/blog/archive/2005/03/11/1886.aspx
if you need to convert it to VB try this
http://converter.telerik.com/Default.aspx
Re: Programatically create (and remove) linkbuttons
Yes Brin thats exactly right, basically clicking a hotspot postback and adds to the breadcrumb (and adds to collection so it can be re-created on next page load).
Clicking the beadcrumb linkbuttons posts back with the previous maps command argument to load it, and should delete all linkbuttons to the right of the clicked one.
Your spot on when you say I need to see which button caused the postback on page load, rather than lettign page load and getting this from linkbuttons command argument.
I'll read the article and let you know. Thansk for the quick reply.
Re: Programatically create (and remove) linkbuttons
I have an inking that what you really need is a Repeater control instead of adding each LinkButton/Label inside the loop.
Do you want me to elaborate on this?
Re: Programatically create (and remove) linkbuttons
Pradeep1210
I think your exactly right, I use repeaters all the time so dont need you to elaborate.
I cant believe I didnt think of this earlier, now you mention it it seems blindingly obvious.
Thanks
Re: Programatically create (and remove) linkbuttons
Ive done it easily with the repeater thanks, took five minutes and works perfectly
In summary:
Page load processes before any control handlers fire
Think carefully about the best approach to the problem
Im an idiot
Thanks both for your help