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.
|