ImageMap 控件
网页通常包含复杂的图形,当单击图形的不同部分时,会有不同的行为。ASP.NET 开发人员能够使用多种技巧来实现这个设计:
- 拼接的图像控件。当多个无边界的图像一张挨一张仔细的定位后,看起来就像是一幅图。于是,你可以分别处理每一个控件的单击,这种方式对于已经定义矩形边界的按钮和导航控件很有效。
- ImageButton 。当 ImageButton 被单击时,它提供单击发生处的坐标。你可以在服务器端检测这些坐标,通过编程确定哪一部分被单击了。这种方式灵活但是编码较繁琐容易出错。
- ImageMap 。你可以定义独立的区域,并唯一的命名每个区域。只有鼠标落于某个定义的区域内,指针才会变成手形,因此,这个方法对于有小热点的细致的图像很有效。
ImageMap 控件是对于 HTML 中用于定义图像映射(image map)的 <map> 和 <area> 标签的服务器端抽象。ImageMap 将自己呈现为一个 <map> 标签。通过向 ImageMap.HotSpots 集合中添加 HotSpot 对象来定义区域,每个区域被呈现为一个 <area> 标签。在 <map> 之前,ASP.NET 呈现出显示图片并使用图像区域的带链接的 <img> 标签。
创建热点
为了定义可以单击的区域,需要向 ImageMap.HotSpots 属性里添加 HotSpot 对象。可以使用 3 个派生类:CircleHotSpot、RectangleHotSpot、PolygonHotSpot,它们与 HTML 标准中定义的 3 种形状类型一一对应。
在这之前,需要获知穿件的热点的确切坐标。VS 的 ImageMap 设计器不支持可视化的定义区域。建议使用别的 HTML 编辑器工具做这件事。
调整好热点之后,可以查看源代码来确定坐标。
- 定义矩形时,只需要左上角和右下角的坐标。
- 定义任意多边形时,你可以随意定义多个定点。浏览器从一点出发到另一点画线来创建形状。依据 HTML 标准,建议以起始点作为结束点。
- 定义圆形时,只需指明圆心坐标及半径即可。例如 <area shape=”circle” coords=”272, 83, 83”…>,圆心位于(272,83),半径 83 像素。
热点可以重叠,但是先定义的热点才会处理单击事件。
一旦确定了热点,就可以添加相应的 HotSpot 对象了。这里以矩形热点示例:
不必手工编写这段代码,选中控件编辑属性 HotSpots 即可。
这里贴图显示不出鼠标指针的效果…
处理热点单击
一个热点被单击,可以激发两个动作中的一个:导航至新页面 或 回传你的页面。
要选择使用哪个动作,需要设置 HotSpotMode 属性。设置 ImageMap.HotSpotMode 时将影响所有的热点。你当然也可以为每个热点设置 HotSpotMode 属性来覆盖这一设置。这就使得你可以让某些热点回传页面,而另一些则触发导航。
- HotSpotMode.Inactive :完全禁用热点。
- HotSpotMode.Navigate :全部启用导航,需要设置每个 HotSpot.NavigateUrl 的值。
- HotSpotMode.PostBack :全部启用回传,需要设置每个 HotSpot.PosBackValue 的值,这使得 Click 事件能分辨哪个热点触发了回传。
添加了这些细节的一段页面代码:
OnClick="ImageMap1_Click">
protected void ImageMap1_Click(object sender, ImageMapEventArgs e)
{
Label1.Text = "You clicked: " + e.PostBackValue;
}
自定义热点
ImageMap 控件支持任何从 HotSpot 派生的热点类。
ASP.NET 有 3 个热点类分别对应于 HTML 标准中定义的 3 类基本 <area> 形状。然而,你也可以通过 HotSpot 类派生来创建自己的热点。不过,显然一个自定义热点类并不能做超出 HTML 标准的任何事情。例如,椭圆和其他曲线画出的形状更漂亮,但是却不可用。
不过,你仍可以使用多变类型来创建很多复杂的多边形,如三角形、八边形、菱形等这些高级模型。
下面这个示例展示了一个简单的自定义三角形,基于中心点,宽度和高度创建:
namespace CustomHotSpots
{
public class TriangleHotSpot : HotSpot
{
public int Width
{
get { return (int)ViewState["Width"]; }
set { ViewState["Width"] = value; }
}
public int Height
{
get { return (int)ViewState["Height"]; }
set { ViewState["Height"] = value; }
}
public int X
{
get { return (int)ViewState["X"]; }
set { ViewState["X"] = value; }
}
public int Y
{
get { return (int)ViewState["Y"]; }
set { ViewState["Y"] = value; }
}
public TriangleHotSpot()
{
Width = 0;
Height = 0;
X = 0;
Y = 0;
}
// 必须覆盖 MarkupName 属性来返回你创建的形状的类型
// 有效的选项只有 circle, rectangle, polygon 之一
// 它被应用于 标签的 shape 特性中
protected override string MarkupName
{
get { return "polygon"; }
}
// 最后需要覆盖此方法返回坐标特性的字符串
// 对于多边形,必须是一个逗号间隔的 X,Y 对组成的点序列
public override string GetCoordinates()
{
int topX = X;
int topY = Y - Height / 2;
int btmLeftX = X - Width / 2;
int btmLeftY = Y + Height / 2;
int btmRightX = X + Width / 2;
int btmRightY = Y + Height / 2;
return topX.ToString() + "," + topY.ToString() + "," +
btmLeftX.ToString() + "," + btmLeftY.ToString() + "," +
btmRightX.ToString() + "," + btmRightY.ToString() + ",";
}
}
}
现在,可以像使用自定义控件那样使用自定义热点了。首先,为标签注册一下前缀:
<%@ Register TagPrefix="chs" Namespace="CustomHotSpots" %>
现在单击三角形热点区域,会将用户重定向到一个新的 URL:
X="140" Y="50" Width="75" Height="80" />