CODEDIGEST
Home » Articles
Search
 

Technologies
 

Sponsored links
 

CodeDigest Navigation
 

Technology News
No News Feeds available at this time.
 

Community News
No News Feeds available at this time.
 
Picasa Style Photo Album Using ListView Control in ASP.Net 3.5

By Satheesh Babu
Posted On Apr 09,2009
Article Rating:
Be first to rate
this article.
No of Comments: 25
Category: ASP.Net
Print this article.

Picasa Style Photo Album Using ListView Control in ASP.Net 3.5

 

Introduction

ListView is a new databound control that is shipped with ASP.Net 3.5.  Read my previous article -   ListView Control in ASP.Net 3.5 which elaborates the usage of this new control.  ListView control is one of the most flexible databound control that can be used to present the data in any custom format. Moving forward, in this article we will use this new control to create Google’s Picasa style photo album. Even though, picasa has more features we will implement only the display of albums and its photos using ListView control.

Overview

Google’s Picasa doesn’t need an introduction since it’s one of the widely used photo sharing destination on net. Picasa is a web based photo album where users can create photo album and upload the photos to share it with their dears and nears.  Before moving into the article, it will be better if know a little bit of how it works, at least the features which we are going to implement in this article using ListView control. Picasa displays a list of albums with one of the photos as album cover (Figure 1). Clicking on any album will take to a page where it displays list of photos uploaded under the album in thumbnail view (Figure 2). User can view the full image by clicking any thumbnail image. Once the full image is loaded, use can navigate to next and previous photos (Figure 3).  I am not a good UI designer; kindly excuse me for the bad UI designs.

 

Figure 1 - Albums

Photo Album - CodeDigest.Com,Album.png

 

Figure 2 – Photos in Thumbnail View

Photo Album - CodeDigest.Com,photos.png

 

Figure 3 – Full photo view

Photo Album - CodeDigest.Com,photoviewer.png

Moving forward, we will implement a photo album that works similar to Picasa using ListView control.  As I said earlier, Picasa offers lot many features but we will implement only the above said ones to understand the flexibilities offered by ListView control in ASP.Net 3.5.

 

Understanding DataBase Design

Before moving to the actual implementation, we will first see the database design which stores the album information to understand the implementation better.  Refer the below database diagram,

The database contains 2 tables,

1.      Album – Stores information’s about album. DefaultPhotID column stores ID of the photo that is set as album cover.

2.      PhotAlbum – It contains all the information about albums. The column Photo will store location of the photo where it is uploaded.

You can increase the column size as per your need.

 

Photo Album - CodeDigest.Com,DB.png

In coming sections, we will see how we can implement this with ListView control.

 

Creating Albums List

In Album List Page, we will display 3 albums in a row in Tiled format i.e. to repeat the display of items horizontally, Refer Figure 1. To create a new Album, a “Create New Album” link will be displayed at the end of the ListView control. This link will be automatically moved to the last column of the ListView control whenever a new Album is added. We will see how this can be implemented with ListView control.

To display data in ListView control, we have to first define the mandatory templates, Layout Template and Item Template.  Read my previous article - ListView Control in ASP.Net 3.5 to gain more knowledge on this.

Additionally, we will use Group Template to group the data in tiled format. We can restrict the number of items in a row by using a property called GroupItemCount.

To display “Create New Album” link, we can use another ListView template called InsertItemTemplate. The content in InsertItemTemplate will be displayed to insert a new item in the ListView.  We can set the property called InsertItemPosition to dictate where we can display the InsertItemTemplate. In our case, it is LastItem.

 

So, our final ListView control code will look like,

 

<asp:ListView ID="lvAlbums" runat="server"

            DataSourceID="SqlDataSource1" GroupItemCount="3"

            InsertItemPosition="LastItem">           

            <LayoutTemplate>               

                    <table border="1">

                       <tr ID="groupPlaceholder" runat="server">

                       </tr>

                    </table>                      

            </LayoutTemplate>                                             

            <GroupTemplate>

                    <tr>

                        <td ID="itemPlaceholder" runat="server">

                        </td>

                    </tr>

             </GroupTemplate>            

             <ItemTemplate>

                    <td id="Td3" width="150px" height="150px" align="center" style="background-color: #e8e8e8;color: #333333;">

                    <asp:HiddenField ID="hfPhotoID" runat="server" Value='<%# Eval("DefaultPhotID") %>' />

                    <a href='<%# "Photos.aspx?AlbumID="+Eval("AlbumID") %>'>

                    <asp:Image CssClass="Timg" runat="server" ID="imPhoto" ImageUrl='<%# "ThumbNail.ashx?ImURL="+Eval("Photo") %>' />

                    </a>

                    <br />                   

                    <b><asp:Label ID="lblAlbumName" runat="server" Text='<%# Eval("AlbumName") %>'></asp:Label>   </b>

                    </td>               

                </ItemTemplate>

                

                <InsertItemTemplate>

                <td id="Td3" width="150px" height="150px" runat="server" align="center" style="background-color: #e8e8e8;color: #333333;">

                <a href="CreateAlbum.aspx">                   

                    Create New Album

                </a>

                </td>             

                </InsertItemTemplate>            

            </asp:ListView>

 

        <asp:SqlDataSource ID="SqlDataSource1" runat="server"

            ConnectionString="<%$ ConnectionStrings:ConnectionString %>"

            SelectCommand="SELECT Album.AlbumID, Album.DefaultPhotID, Album.AlbumName, PhotAlbum.Photo FROM Album INNER JOIN PhotAlbum ON Album.DefaultPhotID = PhotAlbum.PhotoID">

        </asp:SqlDataSource>

 

In the above code, I have used GroupItemCount as 3. Increase this value to display more number of Albums in a row.  I have used SqlDataSource control to bind the data from database.

 

Since, the album cover should be the one of the photo(DefaultPhotID column of Album table) uploaded in the album, we should display its thumbnail version as its album cover. To do this, we will use an HttpHandler[ThumbNail.ashx] which will convert the full image to Thumbnail image.

Below, you can find the HttpHanlder implementation that generates the thumbnail image(100x100) from the original image.

 

<%@ WebHandler Language="C#" Class="ThumbNail" %>

 

using System;

using System.Web;

using System.Drawing;

using System.IO;

 

public class ThumbNail : IHttpHandler {

   

    public void ProcessRequest (HttpContext context) {

        string imageurl = context.Request.QueryString["ImURL"];

        string str = context.Server.MapPath(".") + imageurl;

        Bitmap bmp = new Bitmap(str);

        System.Drawing.Image img = bmp.GetThumbnailImage(100, 100, null, IntPtr.Zero);

        MemoryStream ms = new MemoryStream();

        img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

        byte[] bmpBytes = ms.GetBuffer();

        img.Dispose();

        ms.Close();

 

        context.Response.BinaryWrite(bmpBytes);

        context.Response.End();   

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }

 

}

 

Next, clicking “Create New Album” link will take us to CreateAlbum.aspx page to create new album. Once the album is created, this will further take to photo uploading page (ImageUpload.aspx) to upload images for an album. Refer the below figures,

CreateAlbum.aspx

 Photo Album - CodeDigest.Com,CreateAlbum.aspx

ImageUpload.aspx

Photo Album - CodeDigest.Com,ImageUpload.aspx 

I am not going to discuss about the implementation of these pages as this is not in the scope of the article. You can download the source attached with this article to see it in action. 

 

At last, when a user clicks an Album, he or she will be re-directed to page (photos.aspx) where we should display the list of photos that is uploaded under the album in thumbnail view.




Displaying photos in Thumbnail View

In photos.aspx page, we will accept the AlbumId through the QueryString parameter and populate the ListView control.  Again, we will use GroupTemplate to display 3 photos per row. Refer the Figure 2. In Figure 2, the list of thumbnail photos(content in right) are rendered by the ListView control while content on the left side which displays Album information is handled separately.

 

 To display the thumbnail view of every photo, we will use the same HttpHandler [ThumbNail.ashx] used in Albums page. You can consider saving a thumbnail version of every photo while uploading to improve performance. In this approach, every time when the user views the album it will generate the equivalent thumbnail image which we can really prevent if we do the thumbnail conversion when the user uploading the actual image.  Refer the below link to do this,

Upload image to file system and create thumbnail image on the fly in C# and ASP.Net

 

Finally, ListView control will look like,

<asp:ListView ID="lvPhotos" runat="server" DataKeyNames="AlbumID"

            DataSourceID="SqlDataSource1" GroupItemCount="3">           

            <LayoutTemplate>              

                   <table ID="groupPlaceholderContainer" runat="server" border="0" cellpadding="0" cellspacing="0">

                         <tr ID="groupPlaceholder" runat="server">

                         </tr>

                   </table>                       

            </LayoutTemplate>                       

            <GroupTemplate>

                    <tr ID="itemPlaceholderContainer" runat="server">

                        <td ID="itemPlaceholder" runat="server">

                        </td>

                    </tr>

                </GroupTemplate>          

                <ItemTemplate>

                    <td runat="server" align="center" style="background-color: #e8e8e8;color: #333333;">                   

                    <a href='<%# "PhotoViewer.aspx?PhotoID="+Eval("PhotoID")+"&AlbumID="+ Eval("AlbumID") %>'>

                    <asp:Image CssClass="Timg" runat="server" ID="imPhoto" ImageUrl='<%# "ThumbNail.ashx?ImURL="+Eval("Photo") %>' />

                    </a>

                    </td>               

                </ItemTemplate>            

            </asp:ListView>

 

<asp:SqlDataSource ID="SqlDataSource1" runat="server"

                ConnectionString="<%$ ConnectionStrings:ConnectionString %>"

            SelectCommand="SELECT [PhotoID], [Photo], [PhotoName], [AlbumID] FROM [PhotAlbum] WHERE ([AlbumID] = @AlbumID) ORDER By [PhotoID] ASC"

            onselected="SqlDataSource1_Selected">

                <SelectParameters>

                    <asp:QueryStringParameter DefaultValue="1" Name="AlbumID"

                        QueryStringField="AlbumID" Type="Int32" />

                </SelectParameters>

            </asp:SqlDataSource>

 

Again, I have used SqlDataSource control to bind the data from database. 

To view the full image, users have to click any of the thumbnail images which will load the full image with next and previous button. Next section will help you to do this.

 

Viewing Full Image

Once the user clicks any of thumbnail images we will load the full image in a ListView control(Refer PhotoViewer.aspx in our sample) by accepting AlbumId and PhotoID as query string parameter.  Refer Figure 3 for better understanding. We will also display next and previous button to navigate between the photos in that album.  Unlike the other 2 pages, we will bind the data using our code.

 

In this scenario, we will display one image at a time in ListView control as seen the Figure 3. We will again use GroupTemplate to display the images in ListView.

Note

We can also do this without using GroupTemplate. Using GroupTemplate we can increase the number photos displayed at a time using GroupItemCount property.

 

Next and Previous button is displayed through the DataPager control. Read my article - Paging in ListView in ASP.Net 3.5 to know more about DataPager and Paging in ListView control.

 

So, our ListView control will look like,

<table>

    <tr>

    <td>

        <asp:ListView ID="lvPhotoViewer" runat="server" GroupItemCount="1">

         <LayoutTemplate>               

             <table ID="groupPlaceholderContainer" runat="server" border="1">                              

                  <tr ID="groupPlaceholder" runat="server">

                  </tr>

             </table>                      

         </LayoutTemplate>

              

         <ItemTemplate>

             <td id="Td4" align="center" style="background-color: #eeeeee;">

                    <asp:Image runat="server" ID="imPhoto" Height="450px" Width="450px" ImageUrl='<%# "~"+Eval("Photo") %>' />

                    <br />

                    <asp:Label ID="DefaultPhotIDLabel" runat="server"

                            Text='<%# Eval("PhotoName") %>' />

             </td>

        </ItemTemplate>

  

         <GroupTemplate>

              <tr ID="itemPlaceholderContainer" runat="server">

                   <td ID="itemPlaceholder" runat="server">

                   </td>

              </tr>

        </GroupTemplate>

        </asp:ListView>

    </td>

    </tr>

    <tr>

    <td align="center">

        <asp:DataPager ID="DataPager1" runat="server"

        PagedControlID="lvPhotoViewer" PageSize="1"

        onprerender="DataPager1_PreRender">

        <Fields>

            <asp:NextPreviousPagerField ButtonType="Link"

            PreviousPageText="<< " NextPageText=" >>" />

         </Fields>

        </asp:DataPager>

    </td>

    </tr>

    </table>   

 

CodeBehind

protected void Page_Load(object sender, EventArgs e)

    {

        if (!Page.IsPostBack)

        {

            string photoID = Request.QueryString["PhotoID"];

            string albumID = Request.QueryString["AlbumID"];

            ViewState["hfAlbumID"] = albumID;

            //Get Page number by passing photo id

            int index = GetPageNumber(int.Parse(photoID), int.Parse(albumID));

            DataPager1.SetPageProperties(index, 1, true);         

        }

    }

    /// <summary>

    /// Since the pagesize is 1 the row number can be taken as page number

    /// </summary>

    /// <param name="PhotoID"></param>

    /// <param name="AlbumID"></param>

    /// <returns></returns>

public int GetPageNumber(int PhotoID,int AlbumID)

    {

        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

        con.Open();

        SqlCommand com = new SqlCommand("SELECT PageNumber FROM (SELECT row_number() Over (order by photoid asc) AS PageNumber,photoid,Albumid FROM PhotAlbum where Albumid=" + AlbumID.ToString() + ") As Photos where photoid=" + PhotoID.ToString() + " and Albumid=" + AlbumID.ToString(), con);

        SqlDataReader dr = com.ExecuteReader();

        int pageno = 1;

        if (dr.Read())

        {

            pageno = int.Parse(dr["PageNumber"].ToString());

        }

        dr.Close();

        con.Close();

        return (pageno - 1);      

    }

    public DataTable GetPhoto(string query)

    {

        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);

        SqlDataAdapter ada = new SqlDataAdapter(query, con);

        DataTable dtEmp = new DataTable();

        ada.Fill(dtEmp);

        return dtEmp;

    }  

    protected void DataPager1_PreRender(object sender, EventArgs e)

    {

        lvPhotoViewer.DataSource = GetPhoto("Select * from PhotAlbum where AlbumID = " + ViewState["hfAlbumID"].ToString());

        lvPhotoViewer.DataBind();

    }   

 

Since, we are displaying one image at a time i.e. PageSize is 1, the page number and Row number got from SqlServer 2005 will be same. Hence, GetPageNumber() method will return the Row_Number() of the Thumbnail photo that is clicked to reach this page and it can be used to bind the particular page in ListView control.

Note

Row_Number() will work in Sql Server 2005 and above only. I have used inline query to bind the data from database. You can consider using stored procedures for better performance and also it prevents SQL injection attack.

 

Download the source code attached with this article to see it in action.

Downloads

Download Source

 

Conclusion

Although, Google’s Picasa has lots more features we have implemented a part of its main functionality using ListView control. By now, you would have understood the flexibility of the ListView control in terms displaying data in different formats. Download the source attached in Download section and see it in action.

Happy Coding!!

Similar Articles
You can contribute to CodeDiget.Com:
Donate to CodeDigest.com
Article Feedback
Comments
kkkk
Make clear pictures for understanding
Problem
Hello please send me code for first I display Images dynamically in Listview after displaying images in Listview that images path will save in database please give me code.


Mail: Balakrishna.mankala@gmail.com
comment
where is the log file of the database !!!
problem
i have used these Album List Page if the user has no album initially then the create album(Figure 1 - Albums) not showing how to overcome these please help me its urgent
Mr
I am using VS Express 2010, and using VB.net. I have converted your C# code to VB and is working fine but the problem is the Album Name and the thumbnail picture are not showing on the photos.aspx page. Please help
Fancy
Well done. Useful
Problem
Please solve my problem, i have used ur given source its working well but getting problem when i click back to Album the error is "DataBinding: 'System.Data.DataRowView' does not contain a property with the name 'Photo'"

please help
Thanks
Prob with Download!
Hi...
Article is gr8..But im not able to download the Source..Please provide me a proper link...Will be a gr8 help
Matos
How use " Row_Number() " in sql 2000 ??'
Can't Download
Hi there,,,Your article is good.
But i can't download anymore....
please give me a link ...plz
plzzzzzzzzz
What an awmseoe way to explain this-now I know everything!
What an awmseoe way to explain this-now I know everything!
number of view
how add number of photo viewed using this example.
navigation
how to get photo id by navigating images in list view next and previous
album
wel i say,d wrk done is very useful, it helped me.!!
thanks alot ..
Deleting selected albums
how do i delete seleted Album
Mutch apriciated

Actualy this the first one i have made work on my page
Nice job
Thanx
Excellent Article
Thank you
This is the best article that shows the functionality of the list view thank you so much
amazing
u r amazing developer ,u will shine like star ...best of luck!thanks again! and if u have any more codes please post it ...please give knowledge what u have ..thanks a lot
Hi
Gud Article
problem faced
Sir, i have downloaded the code but when im going to run it on my pc it gives me error at the page "Create album.aspx"

the error is "cannot insert value null into the column album id...." and point me at com.executescalar


please can u help me solving this problem


Thank u in advance...............
How to Modify for Mysql
Excellent article! What I have been searching for!
But sir, how can I modify the function,
public int GetPageNumber(int PhotoID,int AlbumID)

for mysql? my DB is mysql.
Thanks for your kind reply in advence...
Good
Very good
Excellent Article
Gud Article

http://www.plantsourcecode.in
Bravo
Complimenti
Such a very good example
This is very good example of album view

Thank you very much satheesh babu

Keep it up.....