Asp.Net Image Dropdownlist


This article is written by Pon Saravanan  on 21-Feb-11 Last modified on :21-Feb-11





ASP.Net Image Dropdownlist using Repeater

I was searching for ASP.Net Image Dropdownlist that can have a image thumbnail before the text in each item in the list. However, we do not have any option ASP.Net Image Dropdownlist that can contain image thumbnails. WPF does but not ASP.Net. Hence, I started planning to build one for my project. However, it is not a user control or server control. This can be made as server control with necessary changes but this article will be big. I would like to keep it simple and to explain how this can be achieved.

Constructing the Image Dropdownlist

 I was interested in showing this as close as possible to the standard Dropdownlist. I planned to have three main components to construct. The following are the list and hierarchy of the controls used

• Dropdownlist as a HTML DIV
a. Image to show the selected item’s Image
b. Label to show the selected item’s text
c. Button to simulate the look of the Dropdownlist’s arrow
• List window that contains the list of Dropdownlist items to choose
a. Image
b. Linkbutton to raise a Postback event for selection

Down Arrow in ASP.Net Image Dropdownlist

 The only issue in getting closer is due to the down arrow button. I had a look at the character map, found the down arrow, and used it as a text in the down arrow button. For those who does not know what is character map in windows go to start menu ? run ? type charmap and you can select any letters or symbols and copy the respective values. If you are bit worried about the display issues in other platforms because of the Character you have chosen to show the dropdown. You may chose to use a small GIF image.

CSS Classes for styling

 I have used the CSS classes for styling this, so a little knowledge on the CSS is necessary. We used both ID and CSS Class to define the style for the elements. I used the IDs because of simplicity. However, if you are trying to create this as a control, I would suggest using a class name respectively. Reason behind is, if you are using the control inside another control, then the client id depends on it’s control hierarchy. Because of this, you will see that the class is not referenced properly.

Databinding using Linq to SQL

I wanted to explain how to use Repeater to build a Image Dropdownlist, so I just opted to use Linq to SQL as it is quite simple to start with less code. Can be as simple as the following

Dim
DataContext = New NorthWindDataDataContext
Return DataContext.Categories.ToList

Showing Images in the Dropdownlist using a ImageHandler

I wish data for this Dropdownlist to be completely driven from the database table. I have used Northwind Database’s category table. It contains image data for its picture column. And if your picture is in image datatype, we know that we need a Image handler to render the image to the browser. Please refer Asp.Net Image Handler for more information.

Handling the ItemDataBound and ItemCommand

I have used the ItemDatabound to configure the Image’s link and configure the client scripts for the link button. We have used the CSS to make the Linkbutton to look like a normal label.
I have configured the LinkButton to have the command name property as SelectItem, So that I can bubble the event properly to get it at ItemCommand event.  We can even raise another event  named as SelectedIndexChanged to use it for clear separation of this code from target application.

Screen Capture

Before Selection in ASP.Net Image Dropdownlist


 

After Selection in ASP.Net Image Dropdownlist


 

Source Code

Markup (ASPX)


<%@ Page Language="VB" AutoEventWireup="false"
    CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        .DropdownList
        {
            width: 600px;
            height: 30px;
            border-bottom-style: ridge;
            border: ridge 2px silver;
            padding: 0px;
        }
        .DropdownList #imgSelected
        {
            float: left;
            display: none;
            padding-left: 2px;
            padding-top: 2px;
            padding-right: 5px;
        }
        .DropdownList #txtSelected
        {
            width: 530px;
            height: 28px;
            border-width: 0px;
            float: left;
            font-size: large;
            font-family: Georgia;
            padding-top: 4px;
        }
        .DropdownList #btnDownArrow
        {
            height: 30px;
            width: 30px;
            margin-right: 0px;
            float: right;
        }
        .DisplayWindow
        {
         width: 600px;
            border: solid 1px silver;
            display: none;
        }
        .DisplayWindow .DisplayItem
        {
            border-bottom: dotted 1px silver;
            font-size: large;
            font-family: Georgia;
        }
        .DisplayWindow .DisplayItem a
        {
            text-decoration: none;
            color: Gray;
        }
    </style>
    <script type="text/javascript">
        function ShowPanel()
        {
            var pnlDisplayWindow=document.getElementById("pnlDisplayWindow");
            pnlDisplayWindow.style.display="block";
        }
       
        function HidePanel()
        {
            var pnlDisplayWindow=document.getElementById("pnlDisplayWindow");
            pnlDisplayWindow.style.display="none";
        }
      function btnDownArrow_OnClick()
      {
        if(pnlDisplayWindow.style.display=="none")
            ShowPanel();
        else
            HidePanel();
        return false;
      }
      function btnDesc_OnClick(ImgUrl,btnDesc)
      {
            var imgSelected=document.getElementById("imgSelected");
            var txtSelected=document.getElementById("txtSelected");
           
            imgSelected.style.display="block";
            imgSelected.setAttribute("src",ImgUrl);
            txtSelected.innerText=btnDesc;
            HidePanel();
      }
    </script>
</head>
<body onload="javascript:Body_OnLoad();">
    <form id="form1" runat="server">
    <div class="DropdownList">
        <asp:Image runat="server" ID="imgSelected" Width="25" Height="25" />
        <asp:Label runat="server" ID="txtSelected"></asp:Label>
        <asp:Button runat="server" ID="btnDownArrow" Text="?"
            OnClientClick="javascript:btnDownArrow_OnClick();return false;" />
    </div>
    <div id="pnlDisplayWindow" class="DisplayWindow">
        <asp:Repeater runat="server" ID="rptrList">
            <ItemTemplate>
                <div class="DisplayItem">
                    <asp:Image runat="server" ID="imgThumb"
                        Width="25" Height="25" />
                    <asp:LinkButton runat="server" ID="btnDesc"
                        CommandName="SelectItem"></asp:LinkButton>
                </div>
            </ItemTemplate>
        </asp:Repeater>
    </div>
    <script type="text/javascript">
        var pnlDisplayWindow=document.getElementById("pnlDisplayWindow");
       
        function Body_OnLoad()
        {
           
            pnlDisplayWindow.style.display="none";
        }
    </script>
    </form>
</body>
</html>

Code-Behind (ASPX.VB)

Partial Class _Default
    Inherits System.Web.UI.Page
    Protected Sub rptrList_ItemCommand(ByVal source As Object, _
                                       ByVal e As RepeaterCommandEventArgs) _
                                       Handles rptrList.ItemCommand
        If (e.CommandName = "SelectItem") Then
            Dim btnDesc = DirectCast(e.Item.FindControl("btnDesc"), LinkButton)
            Dim imgThumb = DirectCast(e.Item.FindControl("imgThumb"), Image)
            txtSelected.Text = btnDesc.Text
            imgSelected.ImageUrl = imgThumb.ImageUrl
            imgSelected.Style.Add("display", "block") 'display the image
        End If
    End Sub
    Protected Sub rptrList_ItemDataBound(ByVal sender As Object, _
                                         ByVal e As RepeaterItemEventArgs) _
                                         Handles rptrList.ItemDataBound
        If (e.Item.ItemType = ListItemType.AlternatingItem Or _
           e.Item.ItemType = ListItemType.Item) Then
            Dim CurrentRow = DirectCast(e.Item.DataItem, Category)
            Dim btnDesc = DirectCast(e.Item.FindControl("btnDesc"), LinkButton)
            Dim imgThumb = DirectCast(e.Item.FindControl("imgThumb"), Image)
            imgThumb.ImageUrl = "~/CategoryImageHandler.ashx?CategoryId=" & _
                    CurrentRow.CategoryID
            btnDesc.Text = CurrentRow.Description
            btnDesc.Attributes.Add("onclick", "btnDesc_OnClick('" & _
                                   Page.ResolveClientUrl(imgThumb.ImageUrl) & _
                                   "', '" & btnDesc.Text & "');")
        End If
    End Sub
    Protected Sub Page_Load(ByVal sender As Object, _
                            ByVal e As System.EventArgs) Handles Me.Load
        If (Not IsPostBack) Then
            LoadControls()
        End If
    End Sub
    Private Sub LoadControls()
        Dim DataContext = New NorthWindDataDataContext
        rptrList.DataSource = DataContext.Categories
        rptrList.DataBind()
    End Sub
End Class

Image handler(.VB)

<%@ WebHandler Language="VB" Class="CategoryImageHandler" %>
Imports System.IO
Imports System.Linq
Public Class CategoryImageHandler : Implements IHttpHandler
    Private ReadOnly Property CategoryData() As List(Of Category)
        Get
            Dim DataContext = New NorthWindDataDataContext
          
            Return DataContext.Categories.ToList
        End Get
    
    End Property
 
    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Response.Clear()
        context.Response.ContentType = "image/bmp"
      
        Dim CategoryId = context.Request.QueryString("CategoryId")
        If (CategoryId Is Nothing) Then Return
        Dim CurrentCategory = CategoryData.Find(Function(x) x.CategoryID = CategoryId)
        Dim BmpBytes = DirectCast(CurrentCategory.Picture, System.Data.Linq.Binary).ToArray
        Dim NwOffset = 78
 
        context.Response.OutputStream.Write(BmpBytes, NwOffset, BmpBytes.Length - NwOffset)
        context.Response.End()
    End Sub
    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property
End Class




« Previous -







Comments
  • GUEST
    fantastic control, Thank you. 4/12/2011 8:48:57 PM

  • GUEST
    useful artical,thx. 5/26/2011 12:13:52 AM

  • GUEST
    asp+vb all controls using in different coding in websites 6/28/2011 3:37:22 AM


Comments
   
Captcha Image
For you specially:  
Captcha Text Enter the text in the image.(Not Case sensitive)    



Spam Bot Trap



   



Select Theme
White
Blue
Brown
Gray