前言
我們如何創建一個DataGrid列,顯示從數據庫中獲得的圖像?
這是一個經常被問及的關于DataGrid控件的問題,而且其他可以很容易地通過結合你已經知道的關于模板列的內容以及一點點關于HTTP處理句柄(HTTP Handler)的知識來回答。
下面使用NorthWind數據庫的Employees表來在一個DataGrid中顯示數據庫中的圖像。
代碼
--- BindImg.aspx
<%@ Page language="c#" Codebehind="BindImg.aspx.cs" AutoEventWireup="false" Inherits="ShowImg.BindImg" %>
<HTML>
<HEAD>
<title>BindImg</title>
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<FONT face="宋體">
<asp:DataGrid id="MyDataGrid" runat="server" AutoGenerateColumns="False" Width="632px">
<AlternatingItemStyle BackColor="Beige"></AlternatingItemStyle>
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<Columns>
<asp:TemplateColumn HeaderText="Photo">
<ItemTemplate>
<img src='<%# "GetImg.ashx?ID="+DataBinder.Eval(Container.DataItem,"EmployeeID")%>'>
</ItemTemplate>
</asp:TemplateColumn>
<asp:BoundColumn DataField="LastName" HeaderText="Last Name"></asp:BoundColumn>
<asp:BoundColumn DataField="FirstName" HeaderText="First Name"></asp:BoundColumn>
<asp:BoundColumn DataField="title" HeaderText="Title"></asp:BoundColumn>
</Columns>
</asp:DataGrid></FONT>
</form>
</body>
</HTML>
--- BindImg.aspx.cs
using System;
using System.Data;
using System.Drawing;
using System.Web;
using System.Data.SqlClient;
namespace ShowImg
{
/// <summary>
/// BindImg 的摘要說明。
/// </summary>
public class BindImg : System.Web.UI.Page
{
protected System.Web.UI.WebControls.DataGrid MyDataGrid;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此處放置用戶代碼以初始化頁面
if(!Page.IsPostBack)
{
SqlConnection conn = new SqlConnection(@"Server=shoutor\mydb;database=northwind;uid=sa;Pwd=shoutor");
try
{
conn.Open();
SqlCommand cmd = new SqlCommand("select employeeID,lastname,firstname,title from employees",conn);
SqlDataReader reader = cmd.ExecuteReader();
MyDataGrid.DataSource = reader;
MyDataGrid.DataBind();
}
finally
{
conn.Close();
}
}
}
#region Web 窗體設計器生成的代碼
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: 該調用是 ASP.NET Web 窗體設計器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
}
--- GetImg.ashx
<%@ WebHandler Language="C#" Class="ShowImg.GetImg" %>
--- GetImg.aspx.cs
using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace ShowImg
{
/// <summary>
/// GetImg 的摘要說明。
/// </summary>
public class GetImg : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string id = (string)context.Request["id"];
if(id!=null)
{
MemoryStream stream = new MemoryStream();
SqlConnection conn = new SqlConnection(@"Server=shoutor\mydb;database=northwind;uid=sa;Pwd=shoutor");
Bitmap bm = null;
Image image = null;
try
{
conn.Open();
SqlCommand cmd = new SqlCommand("select photo from employees where employeeid='"+id+"'",conn);
byte[] blob = (byte[])cmd.ExecuteScalar();
stream.Write (blob,78,blob.Length-78);
bm = new Bitmap(stream);
int width=48;
int height = (int)(width*((double)bm.Height/(double)bm.Width));
// GetThumbnailImage生成縮略圖
image = bm.GetThumbnailImage(width,height,null,IntPtr.Zero);
context.Response.ContentType = "image/jpeg";
image.Save(context.Response.OutputStream,ImageFormat.Jpeg);
}
finally
{
if(image!=null)
image.Dispose();
if(bm!=null)
bm.Dispose();
stream.Close();
conn.Close();
}
}
}
// 實現成員接口(System.Web.IHttpHandler.IsReusable)
public bool IsReusable
{
get
{
return true;
}
}
}
}
總結
作為額外的補充,ProcessRequest還使用了空架類庫的易用的Image.GetThumbnailImage方法來把位圖縮小到寬度為48像素,同時保持圖象的長寬比。可以使用類似的技術來創建顯示來自其他數據庫圖象的DataGrid。基本的思想是使用模板列來輸出一個引用某個HTTP處理句柄的<img>標簽,并在查詢字符串中包含唯一標識圖片所在的記錄的信息。之后,HTTP處理句柄使用ADO.NET來獲取圖象數據位,并使用GDI+(圖象設備接口+)來構建圖象。