I wanted to add a control that would randomly select an image from the library, and display it in a leftblock on any particular ASPX page in the site. So I created a new custom control. When it loads, it selects a random image. It then generates an image tag in the HTML, with the appropriate image data. The control then wraps a hyperlink around the image; when clicked the link opens up the album that contains the image in question, using the existing PhotoAlbum_Contents.aspx.
This is the new control, put it into a new file called ImageRandom.ascx:
<%@ Control Language="C#" ClassName="ImageRandom" %>
<script runat="server">
public int MaxWidth
{
get
{
object o = ViewState["MaxWidth"];
return (o != null) ? Convert.ToInt32(o.ToString()) : 0;
}
set
{
ViewState["MaxWidth"] = value;
}
}
private int imageId = 0;
protected void Page_PreRender(object sender, System.EventArgs e)
{
int[] x= ImageUtils.SelectRandomPhoto();
Image1.ImageUrl = "ImageFetch.ashx?Size=" + MaxWidth.ToString() + "&ImageID=" + x[0].ToString();
Hyperlink1.NavigateUrl = "PhotoAlbum_Contents.aspx?AlbumId=" + x[1].ToString() + "&ImageID=" + x[0].ToString();
}
</script>
<asp:HyperLink ID="Hyperlink1" runat="server">
<asp:Image ID="Image1" runat="server" CssClass="picture" BorderWidth="1" />
</asp:HyperLink>
To use the control, stuff something like this into an ASPX page:
<%@ Register TagPrefix="Club" TagName="ImageRandom" Src="ImageRandom.ascx" %>
....
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
<div id="body">
<!--Start of left column-->
<div id="columnleft">
...
<div class="leftblock">
<h3>
Photo pick:</h3>
<Club:ImageRandom ID="ImageRandom" runat="server" MaxWidth="180" />
</div>
...
</div>
...
The control references a new static method in the ImageUtils class - so add this to App_Code\ImageHandling.cs :
public static int[] SelectRandomPhoto()
{
SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ClubSiteDB"].ConnectionString);
// randomly select an image
SqlCommand command = new SqlCommand("select MAX(id) from images", connection);
connection.Open();
int maxId = (int)command.ExecuteScalar();
// now, select an imageID randomly, and verify that it is attached to an album (any album)
System.Random rnd = new System.Random();
command = new SqlCommand("select album from images where id=@id", connection);
SqlParameter p0 = new SqlParameter("@id", SqlDbType.Int);
command.Parameters.Add(p0);
int ImageID=0, albumId = 0;
do
{
ImageID = rnd.Next(1, maxId+1);
p0.Value = ImageID;
albumId = (int)command.ExecuteScalar();
} while (albumId == 0);
connection.Close();
return new int[] {ImageID, albumId};
}
Finally, the PhotoAlbum_Contents.aspx page - if you want to open an album to a particular image, you need to add an OnIteBound event handler to the DataList2, like so:
<asp:DataList ID="DataList2" runat="server" DataSourceID="SqlDataSource2" DataKeyField="id"
RepeatColumns="2" CellSpacing="2"
OnItemDataBound="ItemBound"
...
And then this is the ItemBound method, which should also go into that page (Photoalbum_Contents.aspx). What it does is sets the particular photo to "selected" in the list, when that is the "requested" image in the querystring.
private int _requestedImageId=-455;
private int RequestedImageId
{
get
{
if (_requestedImageId == -455)
{
object o = Request.QueryString["ImageID"];
if (o != null)
_requestedImageId = System.Convert.ToInt32(o);
}
return _requestedImageId;
}
}
protected void ItemBound(Object sender, DataListItemEventArgs e)
{
if (e.Item.GetType().Name == "DataListItem")
{
DataListItem item = (DataListItem)e.Item;
System.Data.DataRowView drv = (System.Data.DataRowView)item.DataItem;
if ((int)drv[0] == RequestedImageId)
{
DataList2.SelectedIndex = item.ItemIndex;
item.ControlStyle.CssClass = "selected";
Trace.Write(String.Format("item {0} selected, ID={1}", item.ItemIndex, RequestedImageId));
DataList2_SelectedIndexChanged(null, null);
}
else
{
Trace.Write(String.Format("item {0} NOT selected, ID={1}", item.ItemIndex, RequestedImageId));
}
}
}