Eine einfache Bildergalerie mit ASP.NET
Für ein kleineres Projekt benötigte ich eine einfache Bildergalerie die ich hiermit kurz vorstellen möchte
Folgende Techniken werden genutzt:
Die Bilder sollen aus einem Verzeichnis innerhalb des Webs ausgelesen und dargestellt werden. Wie die Bilder dorthin gelangen, ist erst mal nicht wichtig. Hierfür habe lese ich mit Hilfe der DirectoryInfo die enthaltenen Dateien aus, schreibe die Eigenschaften der einzelnen FileInfos in eine eigene Hilfsklasse und füge diese Klassen einer generischen Liste hinzu:
private IList<ImageFile> getData()
{
DirectoryInfo di = new DirectoryInfo(
Server.MapPath("~/Images/Gallery/"));
IList<ImageFile> files = new List<ImageFile>();
foreach (FileInfo file in di.GetFiles())
files.Add(new ImageFile()
{
FileName = file.Name,
FullName = file.FullName,
FileSize = file.Length,
CreateDate = file.CreationTime,
WriteTime = file.LastWriteTime,
AccessTime = file.LastAccessTime
});
return files;
}
Die Hilfsklasse sieht so aus:
public class ImageFile
{
public string FileName { get; set; }
public string FullName { get; set; }
public long FileSize { get; set; }
public DateTime CreateDate { get; set; }
public DateTime WriteTime { get; set; }
public DateTime AccessTime { get; set; }
public string GetImageLink(int width, int height)
{
string link = "~/ShowImage.ashx?filename=" +
this.FileName;
if (width > 0)
link += "&width=" + width.ToString();
if (height > 0)
link += "&height=" + height.ToString();
return link;
}
}
Die kleine Methode GetImageLink benötige ich nachher im ListView. Sie setzt mir die URL zum generischen Handler mit allen nötigen Parametern zusammen.
Das binden der Liste an das ListView findet im PreRender Event Handler der ListView statt, denn ein Binding im Page_Load führt dazu, das die gewählte Seite erst nach dem zweiten PostBack angezeigt wird:
protected void GalleryListViewPager_PreRender( object sender, EventArgs e)
{
this.GalleryListView.DataSource = getData();
this.GalleryListView.DataBind();
}
Für die ListView benötige ich ein ItemTemplate und ein LayoutTamplate.
<asp:ListView ID="GalleryListView" runat="server">
<LayoutTemplate>
</LayoutTemplate>
<ItemTemplate>
</ItemTemplate>
</asp:ListView>
Das LayoutTemplate enthält die Definition des Containers welches anschließend die Items enthalten soll. Es könnte also die Definition eines TABLE Controls enthalten, oder in meinem Fall eine ungeordnete Liste mit der CSS Klasse "imagelist":
<ul class="imagelist">
<asp:PlaceHolder ID="itemPlaceholder" runat="server" />
</ul>
Das ListView platziert den Inhalt des ItemTemplates in den angegebenen PlaceHolder hinein. Die ID des Placeholder muss "itemPlaceholder" lauten.
Der Inhalt des ItemTemplates sieht wie folgt aus:
<li>
<asp:HyperLink ID="link" runat="server" NavigateUrl='<%# (Container.DataItem as
GO.WebGallery.ImageFile).GetImageLink(600, 0) %>' rel="lightbox[gallery]"
ToolTip='<%# (Container.DataItem as GO.WebGallery.ImageFile).FileName %>'>
<asp:Image ID="image" runat="server" Width="80px" Height="80px"
BorderWidth="1px" ImageUrl='<%# (Container.DataItem as
GO.WebGallery.ImageFile).GetImageLink(80, 80) %>' AlternateText="" />
</asp:HyperLink>
</li>
Wieso eine ungeordnete Liste? Weil eine Bildergalerie nichts anderes ist als eine Liste mit Bildern...
Beim DataBinding mit Objekten liegt aus meiner Sicht ein weiterer klarer Vorteil darin, dass ich hier direkt mit den Objekten arbeiten kann. "Container.DataItem" ist Praktisch eines meiner gebundenen Objekte. Ein Cast ("Container.DataItem as GO.WebGallery.ImageFile") und ich kann bequem auf die Eigenschaften des Objekts zugreifen.
Das Paging übernimmt hier das DataPager Control, welches ich unterhalb der ListView Platziert habe
<asp:DataPager ID="GalleryListViewPager" runat="server"
PagedControlID="GalleryListView" PageSize="12"
OnPreRender="GalleryListViewPager_PreRender">
<Fields>
<asp:NextPreviousPagerField FirstPageText="<<"
ShowFirstPageButton="True" ShowNextPageButton="False"
PreviousPageText="<" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField LastPageText=">>"
ShowLastPageButton="True" ShowPreviousPageButton="False"
NextPageText=">" />
</Fields>
</asp:DataPager>
Die letzte Komponente die ich hier kurz beschreiben möchte, ist der generische HttpHandler. Aufgerufen mit der URL ("~/ShowImage.ashx?filename=100_2116.JPG&width=80&height=80") liefert er das entsprechende Bild in der angegebenen Größe.
Zuerst wird geprüft, ob es von dem angegebenen Bild bereits ein generiertes Thumbnail gibt, wenn nicht wird das Bild in ein Bitmap Objekt geladen und bearbeitet. Mit Hilfe einiger Hilfsmethoden aus dem sharpcms (im Projekt in der Klasse "Tools") werden die Bilder verkleinert und geschärft um anschließend im HttpHandler im Ordner "Thumbs" abgelegt zu werden.
Die Ausgabe des Bildes an den ResponseStream erfolgt mit folgenden Zeilen:
context.Response.ContentType = "image/jpeg";
if (System.IO.File.Exists(thumbPath))
context.Response.TransmitFile(thumbPath);
else
context.Response.TransmitFile(filePath);
Das Projekt kann hier heruntergeladen werden:
WebGallery.zip (ca. 1MB)