Changing Image.Url's in VB.Net when there's a repetitive amount

63 views Asked by At

I have 30 image buttons, shown here is just a small snippet. I need to change the Image.Url from VB code as I read from a database. You can see from the code below what I'm trying to do, but its very repetitive. Is there a way I can shorten all this?

Frontend

<asp:ImageButton ID="box1" alt="Add To Watch List" runat="server" CommandArgument = "1" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box1.gif" />
<asp:ImageButton ID="box2" alt="Add To Watch List" runat="server" CommandArgument = "2" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box2.gif" />
<asp:ImageButton ID="box3" alt="Add To Watch List" runat="server" CommandArgument = "3" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box3.gif" />
<asp:ImageButton ID="box4" alt="Add To Watch List" runat="server" CommandArgument = "4" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box4.gif" />
<asp:ImageButton ID="box5" alt="Add To Watch List" runat="server" CommandArgument = "5" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box5.gif" />
<br />
<asp:ImageButton ID="box6" alt="Add To Watch List" runat="server" CommandArgument = "6" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box6.gif" />
<asp:ImageButton ID="box7" alt="Add To Watch List" runat="server" CommandArgument = "7" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box7.gif" />
<asp:ImageButton ID="box8" alt="Add To Watch List" runat="server" CommandArgument = "8" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box8.gif" />
<asp:ImageButton ID="box9" alt="Add To Watch List" runat="server" CommandArgument = "9" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box9.gif" />
<asp:ImageButton ID="box10" alt="Add To Watch List" runat="server" CommandArgument = "10" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box10.gif" />

VB.Net

   '*** SELECT CARD ENTRANTS ***
    Dim DBConnect91 As New DBConn
    Using db As DbConnection = DBConnect91.Conn("DBConnectionString")
        Dim cmd As SqlCommand = DBConnect91.Command(db, "SelectEntrants")
        cmd.Parameters.Add(New SqlParameter("fileID", SqlDbType.Int, ParameterDirection.Input)).Value = Request.QueryString("oid")
        db.Open()
        Dim DR As SqlDataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
        While DR.Read
             session("accountID") = DR("accountID")
             session("boxNo") = DR("boxNo").ToString

        If session("accountID") = acc.accountID Then
        Select session("boxNo")
            Case "1"
                box1.ImageUrl="~/files/images/icons/boxesFooty/selectedbox1.gif"
            Case "2"
                box2.ImageUrl="~/files/images/icons/boxesFooty/selectedbox2.gif" 
            Case "3"
                box3.ImageUrl="~/files/images/icons/boxesFooty/selectedbox3.gif"
            Case Else 
        End Select
        End If

        End While

        DR.Close()
        DR = Nothing
        cmd.Dispose()
        cmd = Nothing
        db.Dispose()
        db.Close()
    End Using

Protected Sub Box_Click(sender As Object, e As System.EventArgs)
    Dim btn As ImageButton = CType(sender, ImageButton)
    Dim boxNo As Integer = btn.CommandArgument

    Dim acc As New accounts(Membership.GetUser.ProviderUserKey)
    Dim DBConnect As New DBConn
    Using db As DbConnection = DBConnect.Conn("DBConnectionString")
        Dim cmd As SqlCommand = DBConnect.Command(db, "addEntrant")
        cmd.Parameters.Add(New SqlParameter("accountID", SqlDbType.UniqueIdentifier, ParameterDirection.Input)).Value = acc.accountID
        cmd.Parameters.Add(New SqlParameter("fileID", SqlDbType.Int, ParameterDirection.Input)).Value = Request.QueryString("oid")
        cmd.Parameters.Add(New SqlParameter("boxNo", SqlDbType.Int, ParameterDirection.Input)).Value = boxNo
        db.Open()
        cmd.ExecuteNonQuery()
        cmd.Dispose()
        cmd = Nothing
        db.Dispose()
        db.Close()
    End Using
End Sub
3

There are 3 answers

1
Braulio de la Garza On

You could use a Repeater to create multiple ImageButtons, just check the docs

     <asp:Repeater id="Repeater1" runat="server">             
          <ItemTemplate>
               <asp:ImageButton ID="box10" alt="Add To Watch List" runat="server" CommandArgument = "10" class="BoxPriceMenu" OnClick="Box_Click" ImageUrl="~/files/images/icons/boxesFooty/box10.gif" />
          </ItemTemplate>         
      </asp:Repeater>

then you will need to replace the Id, CommandArgument and ImageURL with something like this

 Id='<%# Eval("Id") %>'

And remember, saving images inside the database will be a considerable amount of storage. Don't store them in a database just store the file location details in the database.

0
Olivier Jacot-Descombes On

You could get the image button by name to get rid of the Select Case statement

While DR.Read()
    Dim accountId = DR("accountID")
    Dim boxNo = DR("boxNo").ToString()
    session("accountID") = accountID
    session("boxNo") = boxNo

    If accountID = acc.accountID Then
        Dim box = CType(FindControl("box" & boxNo), ImageButton)
        box.ImageUrl = $"~/files/images/icons/boxesFooty/selectedbox{boxNo}.gif"
    End If
End While
0
Albert D. Kallal On

As suggested, you have repeating buttons, so then consider a "repeater" (this is exactly the kind of task the repeater is designed for).

So, say this markup:

        <asp:Repeater ID="Repeater1" runat="server"
            OnItemDataBound="Repeater1_ItemDataBound" >
            <ItemTemplate>
                <asp:ImageButton ID="mybox" alt="Add To Watch List" runat="server"
                    class="BoxPriceMenu"
                    OnClick="mybox_Click"
                    CommandArgument="<%# Container.ItemIndex %>"
                    style="margin-left:25px;width:128px"
                  />
            </ItemTemplate>
        </asp:Repeater>
        <br />
        <h1 id="ShowChoice" runat="server"></h1>

So, let’s have code behind feed a "table" of 10 things to the above.

So, code behind is this:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadData()
    End If

End Sub

Sub LoadData()

    Dim rstData As New DataTable
    rstData.Columns.Add("Title")
    For i = 1 To 10
        Dim MyNewRow As DataRow = rstData.NewRow
        MyNewRow("Title") = $"Button {i}"

        rstData.Rows.Add(MyNewRow) ' add this row to table
    Next

    ' now bind the data table to repeater to repeat over and over

    Repeater1.DataSource = rstData
    Repeater1.DataBind()


End Sub


Protected Sub Repeater1_ItemDataBound(sender As Object, e As RepeaterItemEventArgs)

    ' this code runs DURING data binding and is triggered for each row of the repeater 
    ' During the binding process. A great place to set the image for each button


    If e.Item.ItemType = ListItemType.Item Or
            e.Item.ItemType = ListItemType.AlternatingItem Then

        ' set the URL for this button image

        Dim iRowIndex As Integer = e.Item.ItemIndex + 1 ' starts at 0, we start at 1
        Dim sURL As String = $"~/Content/Balls/b{iRowIndex}.png"
        Dim OneBut As ImageButton = e.Item.FindControl("mybox")
        OneBut.ImageUrl = sURL


    End If

End Sub

Protected Sub mybox_Click(sender As Object, e As ImageClickEventArgs)

    Dim MyImageBut As ImageButton = sender
    Dim MyRow As RepeaterItem = MyImageBut.NamingContainer

    Debug.Print($"Row click (zero based) = {MyRow.ItemIndex}")

    ShowChoice.InnerText = $"Button ball click = {MyRow.ItemIndex + 1}"


End Sub

Note how simple the above code is. In my case, my image is named b1-b10.

When I run the above, the result is this: enter image description here

So, consider a repeater. Note how above has little code, and has little markup.

For a given row (button) click, we can with ease pick up the "index" of that button, and our code thus is much the same for 5 or 25 buttons.