966bba02bb
Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
517 lines
16 KiB
C#
517 lines
16 KiB
C#
//
|
|
// System.Web.UI.WebControls.SiteMapPath.cs
|
|
//
|
|
// Authors:
|
|
// Lluis Sanchez Gual (lluis@novell.com)
|
|
//
|
|
// (C) 2005 Novell, Inc (http://www.novell.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
|
|
//
|
|
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Web.UI.HtmlControls;
|
|
|
|
namespace System.Web.UI.WebControls
|
|
{
|
|
[Designer ("System.Web.UI.Design.WebControls.SiteMapPathDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
|
|
public class SiteMapPath: CompositeControl
|
|
{
|
|
SiteMapProvider provider;
|
|
|
|
Style currentNodeStyle;
|
|
Style nodeStyle;
|
|
Style pathSeparatorStyle;
|
|
Style rootNodeStyle;
|
|
|
|
ITemplate currentNodeTemplate;
|
|
ITemplate nodeTemplate;
|
|
ITemplate pathSeparatorTemplate;
|
|
ITemplate rootNodeTemplate;
|
|
|
|
static readonly object ItemCreatedEvent = new object();
|
|
static readonly object ItemDataBoundEvent = new object();
|
|
|
|
public event SiteMapNodeItemEventHandler ItemCreated {
|
|
add { Events.AddHandler (ItemCreatedEvent, value); }
|
|
remove { Events.RemoveHandler (ItemCreatedEvent, value); }
|
|
}
|
|
|
|
public event SiteMapNodeItemEventHandler ItemDataBound {
|
|
add { Events.AddHandler (ItemDataBoundEvent, value); }
|
|
remove { Events.RemoveHandler (ItemDataBoundEvent, value); }
|
|
}
|
|
|
|
protected virtual void OnItemCreated (SiteMapNodeItemEventArgs e)
|
|
{
|
|
if (Events != null) {
|
|
SiteMapNodeItemEventHandler eh = (SiteMapNodeItemEventHandler) Events [ItemCreatedEvent];
|
|
if (eh != null) eh (this, e);
|
|
}
|
|
}
|
|
|
|
protected virtual void OnItemDataBound (SiteMapNodeItemEventArgs e)
|
|
{
|
|
if (Events != null) {
|
|
SiteMapNodeItemEventHandler eh = (SiteMapNodeItemEventHandler) Events [ItemDataBoundEvent];
|
|
if (eh != null) eh (this, e);
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (null)]
|
|
[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
|
|
[NotifyParentPropertyAttribute (true)]
|
|
[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
|
|
public Style CurrentNodeStyle {
|
|
get {
|
|
if (currentNodeStyle == null) {
|
|
currentNodeStyle = new Style ();
|
|
if (IsTrackingViewState)
|
|
((IStateManager)currentNodeStyle).TrackViewState ();
|
|
}
|
|
return currentNodeStyle;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (null)]
|
|
[TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
|
|
[PersistenceMode (PersistenceMode.InnerProperty)]
|
|
[Browsable (false)]
|
|
public virtual ITemplate CurrentNodeTemplate {
|
|
get { return currentNodeTemplate; }
|
|
set { currentNodeTemplate = value; UpdateControls (); }
|
|
}
|
|
|
|
[DefaultValueAttribute (null)]
|
|
[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
|
|
[NotifyParentPropertyAttribute (true)]
|
|
[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
|
|
public Style NodeStyle {
|
|
get {
|
|
if (nodeStyle == null) {
|
|
nodeStyle = new Style ();
|
|
if (IsTrackingViewState)
|
|
((IStateManager)nodeStyle).TrackViewState ();
|
|
}
|
|
return nodeStyle;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (null)]
|
|
[TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
|
|
[PersistenceMode (PersistenceMode.InnerProperty)]
|
|
[Browsable (false)]
|
|
public virtual ITemplate NodeTemplate {
|
|
get { return nodeTemplate; }
|
|
set { nodeTemplate = value; UpdateControls (); }
|
|
}
|
|
|
|
[DefaultValueAttribute (-1)]
|
|
[ThemeableAttribute (false)]
|
|
public virtual int ParentLevelsDisplayed {
|
|
get { return ViewState.GetInt ("ParentLevelsDisplayed", -1); }
|
|
set {
|
|
if (value < -1) throw new ArgumentOutOfRangeException ("value");
|
|
ViewState ["ParentLevelsDisplayed"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (PathDirection.RootToCurrent)]
|
|
public virtual PathDirection PathDirection {
|
|
get { return (PathDirection)ViewState.GetInt ("PathDirection", (int)PathDirection.RootToCurrent); }
|
|
set {
|
|
if (value != PathDirection.RootToCurrent && value != PathDirection.CurrentToRoot)
|
|
throw new ArgumentOutOfRangeException ("value");
|
|
ViewState ["PathDirection"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (" > ")]
|
|
[LocalizableAttribute (true)]
|
|
public virtual string PathSeparator {
|
|
get { return ViewState.GetString ("PathSeparator", " > "); }
|
|
set {
|
|
ViewState ["PathSeparator"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (null)]
|
|
[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
|
|
[NotifyParentPropertyAttribute (true)]
|
|
[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
|
|
public Style PathSeparatorStyle {
|
|
get {
|
|
if (pathSeparatorStyle == null) {
|
|
pathSeparatorStyle = new Style ();
|
|
if (IsTrackingViewState)
|
|
((IStateManager)pathSeparatorStyle).TrackViewState ();
|
|
}
|
|
return pathSeparatorStyle;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (null)]
|
|
[TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
|
|
[PersistenceMode (PersistenceMode.InnerProperty)]
|
|
[Browsable (false)]
|
|
public virtual ITemplate PathSeparatorTemplate {
|
|
get { return pathSeparatorTemplate; }
|
|
set { pathSeparatorTemplate = value; UpdateControls (); }
|
|
}
|
|
|
|
[BrowsableAttribute (false)]
|
|
[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
|
|
public SiteMapProvider Provider {
|
|
get {
|
|
if (provider == null) {
|
|
if (this.SiteMapProvider.Length == 0) {
|
|
provider = SiteMap.Provider;
|
|
if (provider == null)
|
|
throw new HttpException ("There is no default provider configured for the site.");
|
|
} else {
|
|
provider = SiteMap.Providers [this.SiteMapProvider];
|
|
if (provider == null)
|
|
throw new HttpException ("SiteMap provider '" + this.SiteMapProvider + "' not found.");
|
|
}
|
|
}
|
|
return provider;
|
|
}
|
|
set {
|
|
provider = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (false)]
|
|
public virtual bool RenderCurrentNodeAsLink {
|
|
get { return ViewState.GetBool ("RenderCurrentNodeAsLink", false); }
|
|
set {
|
|
ViewState ["RenderCurrentNodeAsLink"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute (null)]
|
|
[DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
|
|
[NotifyParentPropertyAttribute (true)]
|
|
[PersistenceModeAttribute (PersistenceMode.InnerProperty)]
|
|
public Style RootNodeStyle {
|
|
get {
|
|
if (rootNodeStyle == null) {
|
|
rootNodeStyle = new Style ();
|
|
if (IsTrackingViewState)
|
|
((IStateManager)rootNodeStyle).TrackViewState ();
|
|
}
|
|
return rootNodeStyle;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (null)]
|
|
[TemplateContainer (typeof(SiteMapNodeItem), BindingDirection.OneWay)]
|
|
[PersistenceMode (PersistenceMode.InnerProperty)]
|
|
[Browsable (false)]
|
|
public virtual ITemplate RootNodeTemplate {
|
|
get { return rootNodeTemplate; }
|
|
set { rootNodeTemplate = value; UpdateControls (); }
|
|
}
|
|
|
|
[DefaultValueAttribute (true)]
|
|
[ThemeableAttribute (false)]
|
|
public virtual bool ShowToolTips {
|
|
get { return ViewState.GetBool ("ShowToolTips", true); }
|
|
set {
|
|
ViewState ["ShowToolTips"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[DefaultValueAttribute ("")]
|
|
[ThemeableAttribute (false)]
|
|
public virtual string SiteMapProvider {
|
|
get { return ViewState.GetString ("SiteMapProvider", ""); }
|
|
set {
|
|
ViewState ["SiteMapProvider"] = value;
|
|
UpdateControls ();
|
|
}
|
|
}
|
|
|
|
[Localizable (true)]
|
|
public virtual string SkipLinkText
|
|
{
|
|
get { return ViewState.GetString ("SkipLinkText", "Skip Navigation Links"); }
|
|
set { ViewState["SkipLinkText"] = value; }
|
|
}
|
|
|
|
|
|
void UpdateControls ()
|
|
{
|
|
ChildControlsCreated = false;
|
|
}
|
|
|
|
public override void DataBind ()
|
|
{
|
|
base.DataBind ();
|
|
|
|
/* the child controls get bound in
|
|
* base.DataBind */
|
|
foreach (Control c in Controls) {
|
|
if (c is SiteMapNodeItem) {
|
|
SiteMapNodeItem it = (SiteMapNodeItem)c;
|
|
OnItemDataBound (new SiteMapNodeItemEventArgs (it));
|
|
}
|
|
}
|
|
}
|
|
|
|
protected internal override void CreateChildControls ()
|
|
{
|
|
Controls.Clear ();
|
|
CreateControlHierarchy ();
|
|
DataBind ();
|
|
}
|
|
|
|
protected virtual void CreateControlHierarchy ()
|
|
{
|
|
ArrayList nodes = new ArrayList ();
|
|
SiteMapNode node = Provider.CurrentNode;
|
|
if (node == null) return;
|
|
|
|
int levels = ParentLevelsDisplayed != -1 ? ParentLevelsDisplayed + 1 : int.MaxValue;
|
|
|
|
while (node != null && levels > 0) {
|
|
if (nodes.Count > 0) {
|
|
SiteMapNodeItem sep = new SiteMapNodeItem (nodes.Count, SiteMapNodeItemType.PathSeparator);
|
|
InitializeItem (sep);
|
|
SiteMapNodeItemEventArgs sargs = new SiteMapNodeItemEventArgs (sep);
|
|
OnItemCreated (sargs);
|
|
nodes.Add (sep);
|
|
}
|
|
|
|
SiteMapNodeItemType nt;
|
|
if (nodes.Count == 0)
|
|
nt = SiteMapNodeItemType.Current;
|
|
else if (node.ParentNode == null)
|
|
nt = SiteMapNodeItemType.Root;
|
|
else
|
|
nt = SiteMapNodeItemType.Parent;
|
|
|
|
SiteMapNodeItem it = new SiteMapNodeItem (nodes.Count, nt);
|
|
it.SiteMapNode = node;
|
|
InitializeItem (it);
|
|
|
|
SiteMapNodeItemEventArgs args = new SiteMapNodeItemEventArgs (it);
|
|
OnItemCreated (args);
|
|
|
|
nodes.Add (it);
|
|
node = node.ParentNode;
|
|
levels--;
|
|
}
|
|
|
|
if (PathDirection == PathDirection.RootToCurrent) {
|
|
for (int n=nodes.Count - 1; n>=0; n--)
|
|
Controls.Add ((Control)nodes[n]);
|
|
} else {
|
|
for (int n=0; n<nodes.Count; n++)
|
|
Controls.Add ((Control)nodes[n]);
|
|
}
|
|
}
|
|
|
|
protected virtual void InitializeItem (SiteMapNodeItem item)
|
|
{
|
|
switch (item.ItemType) {
|
|
case SiteMapNodeItemType.Root:
|
|
if (RootNodeTemplate != null) {
|
|
item.ApplyStyle (NodeStyle);
|
|
item.ApplyStyle (RootNodeStyle);
|
|
RootNodeTemplate.InstantiateIn (item);
|
|
}
|
|
else if (NodeTemplate != null) {
|
|
item.ApplyStyle (NodeStyle);
|
|
item.ApplyStyle (RootNodeStyle);
|
|
NodeTemplate.InstantiateIn (item);
|
|
}
|
|
else {
|
|
WebControl c = CreateHyperLink (item);
|
|
c.ApplyStyle (NodeStyle);
|
|
c.ApplyStyle (RootNodeStyle);
|
|
item.Controls.Add (c);
|
|
}
|
|
break;
|
|
|
|
case SiteMapNodeItemType.Current:
|
|
if (CurrentNodeTemplate != null) {
|
|
item.ApplyStyle (NodeStyle);
|
|
item.ApplyStyle (CurrentNodeStyle);
|
|
CurrentNodeTemplate.InstantiateIn (item);
|
|
}
|
|
else if (NodeTemplate != null) {
|
|
item.ApplyStyle (NodeStyle);
|
|
item.ApplyStyle (CurrentNodeStyle);
|
|
NodeTemplate.InstantiateIn (item);
|
|
} else if (RenderCurrentNodeAsLink) {
|
|
HyperLink c = CreateHyperLink (item);
|
|
c.ApplyStyle (NodeStyle);
|
|
c.ApplyStyle (CurrentNodeStyle);
|
|
item.Controls.Add (c);
|
|
} else {
|
|
Literal c = CreateLiteral (item);
|
|
item.ApplyStyle (NodeStyle);
|
|
item.ApplyStyle (CurrentNodeStyle);
|
|
item.Controls.Add (c);
|
|
}
|
|
break;
|
|
|
|
case SiteMapNodeItemType.Parent:
|
|
if (NodeTemplate != null) {
|
|
item.ApplyStyle (NodeStyle);
|
|
NodeTemplate.InstantiateIn (item);
|
|
}
|
|
else {
|
|
WebControl c = CreateHyperLink (item);
|
|
c.ApplyStyle (NodeStyle);
|
|
item.Controls.Add (c);
|
|
}
|
|
break;
|
|
|
|
case SiteMapNodeItemType.PathSeparator:
|
|
if (PathSeparatorTemplate != null) {
|
|
item.ApplyStyle (PathSeparatorStyle);
|
|
PathSeparatorTemplate.InstantiateIn (item);
|
|
} else {
|
|
Literal h = new Literal ();
|
|
h.Text = HttpUtility.HtmlEncode (PathSeparator);
|
|
item.ApplyStyle (PathSeparatorStyle);
|
|
item.Controls.Add (h);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
HyperLink CreateHyperLink (SiteMapNodeItem item)
|
|
{
|
|
HyperLink h = new HyperLink ();
|
|
h.Text = item.SiteMapNode.Title;
|
|
h.NavigateUrl = item.SiteMapNode.Url;
|
|
if (ShowToolTips)
|
|
h.ToolTip = item.SiteMapNode.Description;
|
|
return h;
|
|
}
|
|
|
|
Literal CreateLiteral (SiteMapNodeItem item)
|
|
{
|
|
Literal h = new Literal ();
|
|
h.Text = item.SiteMapNode.Title;
|
|
return h;
|
|
}
|
|
|
|
protected override void LoadViewState (object savedState)
|
|
{
|
|
if (savedState == null) {
|
|
base.LoadViewState (null);
|
|
return;
|
|
}
|
|
|
|
object[] states = (object[]) savedState;
|
|
base.LoadViewState (states [0]);
|
|
|
|
if (states[1] != null) ((IStateManager)CurrentNodeStyle).LoadViewState (states[1]);
|
|
if (states[2] != null) ((IStateManager)NodeStyle).LoadViewState (states[2]);
|
|
if (states[3] != null) ((IStateManager)PathSeparatorStyle).LoadViewState (states[3]);
|
|
if (states[4] != null) ((IStateManager)RootNodeStyle).LoadViewState (states[4]);
|
|
}
|
|
|
|
[MonoTODO ("why override?")]
|
|
protected override void OnDataBinding (EventArgs e)
|
|
{
|
|
base.OnDataBinding (e);
|
|
}
|
|
|
|
[MonoTODO ("why override?")]
|
|
protected internal override void Render (HtmlTextWriter writer)
|
|
{
|
|
base.Render (writer);
|
|
}
|
|
|
|
protected internal override void RenderContents (HtmlTextWriter writer)
|
|
{
|
|
string skip_id = ClientID + "_SkipLink";
|
|
string altText = SkipLinkText;
|
|
bool needAnchor = !String.IsNullOrEmpty (altText);
|
|
|
|
if (needAnchor) {
|
|
// Anchor start
|
|
writer.AddAttribute (HtmlTextWriterAttribute.Href, "#" + skip_id);
|
|
writer.RenderBeginTag (HtmlTextWriterTag.A);
|
|
|
|
// Image
|
|
writer.AddAttribute (HtmlTextWriterAttribute.Alt, altText);
|
|
writer.AddAttribute (HtmlTextWriterAttribute.Height, "0");
|
|
writer.AddAttribute (HtmlTextWriterAttribute.Width, "0");
|
|
writer.AddAttribute (HtmlTextWriterAttribute.Src, Page.ClientScript.GetWebResourceUrl (typeof (SiteMapPath), "transparent.gif"));
|
|
writer.AddStyleAttribute (HtmlTextWriterStyle.BorderWidth, "0px");
|
|
writer.RenderBeginTag (HtmlTextWriterTag.Img);
|
|
writer.RenderEndTag ();
|
|
|
|
writer.RenderEndTag ();
|
|
}
|
|
|
|
base.RenderContents (writer);
|
|
|
|
if (needAnchor) {
|
|
writer.AddAttribute(HtmlTextWriterAttribute.Id, skip_id);
|
|
writer.RenderBeginTag(HtmlTextWriterTag.A);
|
|
writer.RenderEndTag();
|
|
}
|
|
}
|
|
|
|
protected override object SaveViewState ()
|
|
{
|
|
object[] state = new object [5];
|
|
state [0] = base.SaveViewState ();
|
|
|
|
if (currentNodeStyle != null) state [1] = ((IStateManager)currentNodeStyle).SaveViewState ();
|
|
if (nodeStyle != null) state [2] = ((IStateManager)nodeStyle).SaveViewState ();
|
|
if (pathSeparatorStyle != null) state [3] = ((IStateManager)pathSeparatorStyle).SaveViewState ();
|
|
if (rootNodeStyle != null) state [4] = ((IStateManager)rootNodeStyle).SaveViewState ();
|
|
|
|
for (int n=0; n<state.Length; n++)
|
|
if (state [n] != null) return state;
|
|
return null;
|
|
}
|
|
|
|
protected override void TrackViewState ()
|
|
{
|
|
base.TrackViewState();
|
|
if (currentNodeStyle != null) ((IStateManager)currentNodeStyle).TrackViewState();
|
|
if (nodeStyle != null) ((IStateManager)nodeStyle).TrackViewState();
|
|
if (pathSeparatorStyle != null) ((IStateManager)pathSeparatorStyle).TrackViewState();
|
|
if (rootNodeStyle != null) ((IStateManager)rootNodeStyle).TrackViewState();
|
|
}
|
|
}
|
|
}
|
|
|