e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
335 lines
12 KiB
C#
335 lines
12 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="ImageMap.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
namespace System.Web.UI.WebControls {
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Globalization;
|
|
using System.Web.UI;
|
|
using System.Web.UI.WebControls;
|
|
using System.Web.Util;
|
|
using System.Web;
|
|
|
|
/// <devdoc>
|
|
/// <para>ImageMap class. Provides support for multiple
|
|
/// region-defined actions within an image.</para>
|
|
/// </devdoc>
|
|
[
|
|
DefaultEvent("Click"),
|
|
DefaultProperty("HotSpots"),
|
|
ParseChildren(true, "HotSpots"),
|
|
SupportsEventValidation,
|
|
]
|
|
public class ImageMap : Image, IPostBackEventHandler {
|
|
|
|
private static readonly object EventClick = new object();
|
|
private bool _hasHotSpots;
|
|
private HotSpotCollection _hotSpots;
|
|
|
|
[
|
|
Browsable(true),
|
|
EditorBrowsableAttribute(EditorBrowsableState.Always)
|
|
]
|
|
public override bool Enabled {
|
|
get {
|
|
return base.Enabled;
|
|
}
|
|
set {
|
|
base.Enabled = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>Gets the HotSpotCollection with defines the regions of ImageMap hot spots.</para>
|
|
/// </devdoc>
|
|
[
|
|
WebCategory("Behavior"),
|
|
WebSysDescription(SR.ImageMap_HotSpots),
|
|
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
|
|
NotifyParentProperty(true),
|
|
PersistenceMode(PersistenceMode.InnerDefaultProperty)
|
|
]
|
|
public HotSpotCollection HotSpots {
|
|
get {
|
|
if (_hotSpots == null) {
|
|
_hotSpots = new HotSpotCollection();
|
|
if (IsTrackingViewState) {
|
|
((IStateManager)_hotSpots).TrackViewState();
|
|
}
|
|
}
|
|
return _hotSpots;
|
|
}
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>Gets or sets the HotSpotMode to either postback or navigation.</para>
|
|
/// </devdoc>
|
|
[
|
|
WebCategory("Behavior"),
|
|
DefaultValue(HotSpotMode.NotSet),
|
|
WebSysDescription(SR.HotSpot_HotSpotMode),
|
|
]
|
|
public virtual HotSpotMode HotSpotMode {
|
|
get {
|
|
object obj = ViewState["HotSpotMode"];
|
|
return (obj == null) ? HotSpotMode.NotSet : (HotSpotMode)obj;
|
|
}
|
|
set {
|
|
if (value < HotSpotMode.NotSet || value > HotSpotMode.Inactive) {
|
|
throw new ArgumentOutOfRangeException("value");
|
|
}
|
|
ViewState["HotSpotMode"] = value;
|
|
}
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>Gets or sets the name of the window for navigation.</para>
|
|
/// </devdoc>
|
|
[
|
|
WebCategory("Behavior"),
|
|
DefaultValue(""),
|
|
WebSysDescription(SR.HotSpot_Target),
|
|
]
|
|
public virtual string Target {
|
|
get {
|
|
object value = ViewState["Target"];
|
|
return (value == null)? String.Empty : (string)value;
|
|
}
|
|
set {
|
|
ViewState["Target"] = value;
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>The event raised when a hotspot is clicked.</para>
|
|
/// </devdoc>
|
|
[
|
|
Category("Action"),
|
|
WebSysDescription(SR.ImageMap_Click)
|
|
]
|
|
public event ImageMapEventHandler Click {
|
|
add {
|
|
Events.AddHandler(EventClick, value);
|
|
}
|
|
remove {
|
|
Events.RemoveHandler(EventClick, value);
|
|
}
|
|
}
|
|
|
|
|
|
/// <internalonly/>
|
|
/// <devdoc>
|
|
/// <para>Overridden to add the "usemap" attribute the the image tag.
|
|
/// Overrides WebControl.AddAttributesToRender.</para>
|
|
/// </devdoc>
|
|
protected override void AddAttributesToRender(HtmlTextWriter writer) {
|
|
base.AddAttributesToRender(writer);
|
|
|
|
if (_hasHotSpots) {
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Usemap, "#ImageMap" + ClientID, false);
|
|
}
|
|
}
|
|
|
|
/// <devdoc>
|
|
/// <para>Restores view-state information that was saved by SaveViewState.
|
|
/// Implements IStateManager.LoadViewState.</para>
|
|
/// </devdoc>
|
|
protected override void LoadViewState(object savedState) {
|
|
object baseState = null;
|
|
object[] myState = null;
|
|
|
|
if (savedState != null) {
|
|
myState = (object[])savedState;
|
|
if (myState.Length != 2) {
|
|
throw new ArgumentException(SR.GetString(SR.ViewState_InvalidViewState));
|
|
}
|
|
|
|
baseState = myState[0];
|
|
}
|
|
|
|
base.LoadViewState(baseState);
|
|
|
|
if ((myState != null) && (myState[1] != null)) {
|
|
((IStateManager)HotSpots).LoadViewState(myState[1]);
|
|
}
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>Called when the user clicks the ImageMap.</para>
|
|
/// </devdoc>
|
|
protected virtual void OnClick(ImageMapEventArgs e) {
|
|
ImageMapEventHandler clickHandler = (ImageMapEventHandler)Events[EventClick];
|
|
if (clickHandler != null) {
|
|
clickHandler(this, e);
|
|
}
|
|
}
|
|
|
|
/// <internalonly/>
|
|
/// <devdoc>
|
|
/// <para>Sends server control content to a provided HtmlTextWriter, which writes the content
|
|
/// to be rendered to the client.
|
|
/// Overrides Control.Render.</para>
|
|
/// </devdoc>
|
|
protected internal override void Render(HtmlTextWriter writer) {
|
|
if (Enabled && !IsEnabled && SupportsDisabledAttribute) {
|
|
// We need to do the cascade effect on the server, because the browser
|
|
// only renders as disabled, but doesn't disable the functionality.
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
|
|
}
|
|
|
|
_hasHotSpots = ((_hotSpots != null) && (_hotSpots.Count > 0));
|
|
|
|
base.Render(writer);
|
|
|
|
if (_hasHotSpots) {
|
|
string fullClientID = "ImageMap" + ClientID;
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Name, fullClientID);
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Id, fullClientID);
|
|
writer.RenderBeginTag(HtmlTextWriterTag.Map);
|
|
|
|
HotSpotMode mapMode = HotSpotMode;
|
|
if (mapMode == HotSpotMode.NotSet) {
|
|
mapMode = HotSpotMode.Navigate;
|
|
}
|
|
HotSpotMode spotMode;
|
|
int hotSpotIndex = 0;
|
|
string controlTarget = Target;
|
|
foreach (HotSpot item in _hotSpots) {
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Shape, item.MarkupName, false);
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Coords, item.GetCoordinates());
|
|
spotMode = item.HotSpotMode;
|
|
if (spotMode == HotSpotMode.NotSet) {
|
|
spotMode = mapMode;
|
|
}
|
|
if (spotMode == HotSpotMode.PostBack) {
|
|
// Make sure the page has a server side form if we are posting back
|
|
if (Page != null) {
|
|
Page.VerifyRenderingInServerForm(this);
|
|
}
|
|
if ((RenderingCompatibility < VersionUtil.Framework40) || IsEnabled) {
|
|
string eventArgument = hotSpotIndex.ToString(CultureInfo.InvariantCulture);
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Href,
|
|
Page.ClientScript.GetPostBackClientHyperlink(this, eventArgument, true));
|
|
}
|
|
}
|
|
else if (spotMode == HotSpotMode.Navigate) {
|
|
if ((RenderingCompatibility < VersionUtil.Framework40) || IsEnabled) {
|
|
String resolvedUrl = ResolveClientUrl(item.NavigateUrl);
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Href, resolvedUrl);
|
|
}
|
|
// Use HotSpot target first, if not specified, use ImageMap's target
|
|
string target = item.Target;
|
|
if (target.Length == 0) target = controlTarget;
|
|
if (target.Length > 0) writer.AddAttribute(HtmlTextWriterAttribute.Target, target);
|
|
}
|
|
else if (spotMode == HotSpotMode.Inactive) {
|
|
writer.AddAttribute("nohref", "true");
|
|
}
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Title, item.AlternateText);
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Alt, item.AlternateText);
|
|
string s = item.AccessKey;
|
|
if (s.Length > 0) {
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Accesskey, s);
|
|
}
|
|
int n = item.TabIndex;
|
|
if (n != 0) {
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Tabindex, n.ToString(NumberFormatInfo.InvariantInfo));
|
|
}
|
|
|
|
writer.RenderBeginTag(HtmlTextWriterTag.Area);
|
|
writer.RenderEndTag();
|
|
++hotSpotIndex;
|
|
}
|
|
writer.RenderEndTag(); // Map
|
|
}
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>Saves any server control view-state changes that have
|
|
/// occurred since the time the page was posted back to the server.
|
|
/// Implements IStateManager.SaveViewState.</para>
|
|
/// </devdoc>
|
|
protected override object SaveViewState() {
|
|
object baseState = base.SaveViewState();
|
|
object hotSpotsState = null;
|
|
|
|
if ((_hotSpots != null) && (_hotSpots.Count > 0)) {
|
|
hotSpotsState = ((IStateManager)_hotSpots).SaveViewState();
|
|
}
|
|
|
|
if ((baseState != null) || (hotSpotsState != null)) {
|
|
object[] savedState = new object[2];
|
|
savedState[0] = baseState;
|
|
savedState[1] = hotSpotsState;
|
|
|
|
return savedState;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
/// <devdoc>
|
|
/// <para>Causes the tracking of view-state changes to the server control.
|
|
/// Implements IStateManager.TrackViewState.</para>
|
|
/// </devdoc>
|
|
protected override void TrackViewState() {
|
|
base.TrackViewState();
|
|
if (_hotSpots != null) {
|
|
((IStateManager)_hotSpots).TrackViewState();
|
|
}
|
|
}
|
|
|
|
#region Implementation of IPostBackEventHandler
|
|
|
|
/// <internalonly/>
|
|
/// <devdoc>
|
|
/// <para>Notifies the server control that caused the postback that
|
|
/// it should handle an incoming post back event.
|
|
/// Implements IPostBackEventHandler.</para>
|
|
/// </devdoc>
|
|
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
|
|
RaisePostBackEvent(eventArgument);
|
|
}
|
|
|
|
|
|
/// <internalonly/>
|
|
/// <devdoc>
|
|
/// <para>Notifies the server control that caused the postback that
|
|
/// it should handle an incoming post back event.
|
|
/// Implements IPostBackEventHandler.</para>
|
|
/// </devdoc>
|
|
protected virtual void RaisePostBackEvent(string eventArgument) {
|
|
ValidateEvent(UniqueID, eventArgument);
|
|
|
|
string postBackValue = null;
|
|
if (eventArgument != null && _hotSpots != null) {
|
|
int hotSpotIndex = Int32.Parse(eventArgument, CultureInfo.InvariantCulture);
|
|
|
|
if (hotSpotIndex >= 0 && hotSpotIndex < _hotSpots.Count) {
|
|
HotSpot hotSpot = _hotSpots[hotSpotIndex];
|
|
HotSpotMode mode = hotSpot.HotSpotMode;
|
|
if (mode == HotSpotMode.NotSet) {
|
|
mode = HotSpotMode;
|
|
}
|
|
if (mode == HotSpotMode.PostBack) {
|
|
postBackValue = hotSpot.PostBackValue;
|
|
}
|
|
}
|
|
}
|
|
// Ignore invalid indexes silently(VSWhidbey 185738)
|
|
if (postBackValue != null) {
|
|
OnClick(new ImageMapEventArgs(postBackValue));
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|