660 lines
28 KiB
C#
660 lines
28 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="MenuAdapter.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
namespace System.Web.UI.WebControls.Adapters {
|
||
|
|
||
|
using System;
|
||
|
using System.Diagnostics;
|
||
|
using System.Globalization;
|
||
|
using System.Text;
|
||
|
using System.Web;
|
||
|
using System.Web.UI;
|
||
|
using System.Web.UI.HtmlControls;
|
||
|
using System.Web.UI.WebControls;
|
||
|
|
||
|
public class MenuAdapter : WebControlAdapter, IPostBackEventHandler {
|
||
|
|
||
|
private string _path;
|
||
|
private Panel _menuPanel;
|
||
|
private int _currentAccessKey = 0;
|
||
|
private MenuItem _titleItem;
|
||
|
|
||
|
protected new Menu Control {
|
||
|
get {
|
||
|
return (Menu) base.Control;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected internal override void LoadAdapterControlState(Object state) {
|
||
|
if (state != null) {
|
||
|
Pair pairState = state as Pair;
|
||
|
if (pairState != null) {
|
||
|
base.LoadAdapterViewState(pairState.First);
|
||
|
_path = (string)pairState.Second;
|
||
|
}
|
||
|
else {
|
||
|
base.LoadAdapterViewState(null);
|
||
|
_path = state as string;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private string Escape(string path) {
|
||
|
// This function escapes \\ so that they don't get replaced because of
|
||
|
// a Netscape 4 bug. Other escapable characters will be escaped by .
|
||
|
// _ becomes __ and \\ becomes \_\
|
||
|
StringBuilder b = null;
|
||
|
|
||
|
if (String.IsNullOrEmpty(path)) {
|
||
|
return String.Empty;
|
||
|
}
|
||
|
|
||
|
int startIndex = 0;
|
||
|
int count = 0;
|
||
|
for (int i = 0; i < path.Length; i++) {
|
||
|
switch (path[i]) {
|
||
|
case '\\':
|
||
|
|
||
|
if (i + 1 < path.Length && path[i + 1] == '\\') {
|
||
|
if (b == null) {
|
||
|
b = new StringBuilder(path.Length + 5);
|
||
|
}
|
||
|
if (count > 0) {
|
||
|
b.Append(path, startIndex, count);
|
||
|
}
|
||
|
b.Append(@"\_\");
|
||
|
i++;
|
||
|
startIndex = i + 1;
|
||
|
count = 0;
|
||
|
}
|
||
|
else {
|
||
|
count++;
|
||
|
}
|
||
|
break;
|
||
|
case '_':
|
||
|
if (b == null) {
|
||
|
b = new StringBuilder(path.Length + 5);
|
||
|
}
|
||
|
|
||
|
if (count > 0) {
|
||
|
b.Append(path, startIndex, count);
|
||
|
}
|
||
|
|
||
|
b.Append("__");
|
||
|
|
||
|
startIndex = i + 1;
|
||
|
count = 0;
|
||
|
break;
|
||
|
default:
|
||
|
count++;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (b == null) {
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
if (count > 0) {
|
||
|
b.Append(path, startIndex, count);
|
||
|
}
|
||
|
|
||
|
return b.ToString();
|
||
|
}
|
||
|
|
||
|
private string UnEscape(string path) {
|
||
|
return path.Replace(@"\\", @"\").Replace(@"\_\", @"\\").Replace("__", "_");
|
||
|
}
|
||
|
|
||
|
protected internal override void OnInit(EventArgs e) {
|
||
|
base.OnInit(e);
|
||
|
Control.Page.RegisterRequiresControlState(Control);
|
||
|
}
|
||
|
|
||
|
protected internal override void OnPreRender(EventArgs e) {
|
||
|
Control.OnPreRender(e, false);
|
||
|
}
|
||
|
|
||
|
protected internal override object SaveAdapterControlState() {
|
||
|
object baseState = base.SaveAdapterViewState();
|
||
|
|
||
|
if (baseState == null) {
|
||
|
if (_path != null) {
|
||
|
return _path;
|
||
|
}
|
||
|
else {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
return new Pair(baseState, _path);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderBreak(HtmlTextWriter writer) {
|
||
|
if (Control.Orientation == Orientation.Vertical) {
|
||
|
writer.WriteBreak();
|
||
|
}
|
||
|
else {
|
||
|
writer.Write(' ');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void RenderBeginTag(HtmlTextWriter writer) {
|
||
|
Menu owner = Control;
|
||
|
// skip link
|
||
|
if (owner.SkipLinkText.Length != 0) {
|
||
|
HyperLink skipLink = new HyperLink();
|
||
|
skipLink.NavigateUrl = '#' + owner.ClientID + "_SkipLink";
|
||
|
skipLink.ImageUrl = owner.SpacerImageUrl;
|
||
|
skipLink.Text = owner.SkipLinkText;
|
||
|
skipLink.Height = Unit.Pixel(1);
|
||
|
skipLink.Width = Unit.Pixel(1);
|
||
|
skipLink.Page = Page;
|
||
|
skipLink.RenderControl(writer);
|
||
|
}
|
||
|
_menuPanel = new Panel();
|
||
|
_menuPanel.ID = owner.UniqueID;
|
||
|
_menuPanel.Page = Page;
|
||
|
// Determine root menu style
|
||
|
MenuItem titleItem;
|
||
|
if (_path != null) {
|
||
|
titleItem = owner.Items.FindItem(_path.Split(TreeView.InternalPathSeparator), 0);
|
||
|
_titleItem = titleItem;
|
||
|
}
|
||
|
else {
|
||
|
titleItem = owner.RootItem;
|
||
|
}
|
||
|
SubMenuStyle rootMenuStyle = owner.GetSubMenuStyle(titleItem);
|
||
|
if (!rootMenuStyle.IsEmpty) {
|
||
|
if (Page != null && Page.SupportsStyleSheets) {
|
||
|
string styleClass = owner.GetSubMenuCssClassName(titleItem);
|
||
|
if (styleClass.Trim().Length > 0) {
|
||
|
_menuPanel.CssClass = styleClass;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
_menuPanel.ApplyStyle(rootMenuStyle);
|
||
|
}
|
||
|
}
|
||
|
_menuPanel.Width = owner.Width;
|
||
|
_menuPanel.Height = owner.Height;
|
||
|
_menuPanel.Enabled = owner.IsEnabled;
|
||
|
_menuPanel.RenderBeginTag(writer);
|
||
|
}
|
||
|
|
||
|
protected override void RenderContents(HtmlTextWriter writer) {
|
||
|
Menu owner = Control;
|
||
|
int position = 0;
|
||
|
if (_titleItem != null) {
|
||
|
if (_titleItem.Depth + 1 >= owner.MaximumDepth) {
|
||
|
throw new InvalidOperationException(SR.GetString(SR.Menu_InvalidDepth));
|
||
|
}
|
||
|
if (!_titleItem.IsEnabled) {
|
||
|
throw new InvalidOperationException(SR.GetString(SR.Menu_InvalidNavigation));
|
||
|
}
|
||
|
RenderItem(writer, _titleItem, position++);
|
||
|
foreach (MenuItem child in _titleItem.ChildItems) {
|
||
|
RenderItem(writer, child, position++);
|
||
|
}
|
||
|
if (PageAdapter != null) {
|
||
|
PageAdapter.RenderPostBackEvent(writer,
|
||
|
owner.UniqueID,
|
||
|
"u",
|
||
|
SR.GetString(SR.MenuAdapter_Up),
|
||
|
SR.GetString(SR.MenuAdapter_UpOneLevel));
|
||
|
}
|
||
|
else {
|
||
|
HyperLink link = new HyperLink();
|
||
|
link.NavigateUrl = Page.ClientScript.GetPostBackClientHyperlink(owner, "u");
|
||
|
link.Text = SR.GetString(SR.MenuAdapter_UpOneLevel);
|
||
|
link.Page = Page;
|
||
|
link.RenderControl(writer);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
else {
|
||
|
position = 1;
|
||
|
}
|
||
|
_path = null;
|
||
|
foreach(MenuItem child in owner.Items) {
|
||
|
RenderItem(writer, child, position++);
|
||
|
if (owner.StaticDisplayLevels > 1 && child.ChildItems.Count > 0) {
|
||
|
RenderContentsRecursive(writer, child, 1, owner.StaticDisplayLevels);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderContentsRecursive(HtmlTextWriter writer, MenuItem parentItem, int depth, int maxDepth) {
|
||
|
int position = 1;
|
||
|
foreach(MenuItem child in parentItem.ChildItems) {
|
||
|
RenderItem(writer, child, position++);
|
||
|
if (depth + 1 < maxDepth && child.ChildItems.Count > 0) {
|
||
|
RenderContentsRecursive(writer, child, depth + 1, maxDepth);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected override void RenderEndTag(HtmlTextWriter writer) {
|
||
|
_menuPanel.RenderEndTag(writer);
|
||
|
// skip link
|
||
|
if (Control.SkipLinkText.Length != 0) {
|
||
|
HtmlAnchor skipAnchor = new HtmlAnchor();
|
||
|
skipAnchor.Name = Control.ClientID + "_SkipLink";
|
||
|
skipAnchor.Page = Page;
|
||
|
skipAnchor.RenderControl(writer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderExpand(HtmlTextWriter writer, MenuItem item, Menu owner) {
|
||
|
string expandImageUrl = item.GetExpandImageUrl();
|
||
|
if (expandImageUrl.Length > 0) {
|
||
|
Image expandImage = new Image();
|
||
|
expandImage.ImageUrl = expandImageUrl;
|
||
|
expandImage.GenerateEmptyAlternateText = true;
|
||
|
if (item.Depth < owner.StaticDisplayLevels) {
|
||
|
|
||
|
expandImage.AlternateText = String.Format(
|
||
|
CultureInfo.CurrentCulture,
|
||
|
owner.StaticPopOutImageTextFormatString,
|
||
|
item.Text);
|
||
|
}
|
||
|
else {
|
||
|
|
||
|
expandImage.AlternateText = String.Format(
|
||
|
CultureInfo.CurrentCulture,
|
||
|
owner.DynamicPopOutImageTextFormatString,
|
||
|
item.Text);
|
||
|
}
|
||
|
// expandImage.ImageAlign = ImageAlign.Right;
|
||
|
expandImage.ImageAlign = ImageAlign.AbsMiddle;
|
||
|
expandImage.Page = Page;
|
||
|
expandImage.RenderControl(writer);
|
||
|
}
|
||
|
else {
|
||
|
writer.Write(' ');
|
||
|
if (item.Depth < owner.StaticDisplayLevels &&
|
||
|
owner.StaticPopOutImageTextFormatString.Length != 0) {
|
||
|
|
||
|
writer.Write(HttpUtility.HtmlEncode(String.Format(
|
||
|
CultureInfo.CurrentCulture,
|
||
|
owner.StaticPopOutImageTextFormatString,
|
||
|
item.Text)));
|
||
|
}
|
||
|
else if (item.Depth >= owner.StaticDisplayLevels &&
|
||
|
owner.DynamicPopOutImageTextFormatString.Length != 0) {
|
||
|
|
||
|
writer.Write(HttpUtility.HtmlEncode(String.Format(
|
||
|
CultureInfo.CurrentCulture,
|
||
|
owner.DynamicPopOutImageTextFormatString,
|
||
|
item.Text)));
|
||
|
}
|
||
|
else {
|
||
|
writer.Write(HttpUtility.HtmlEncode(SR.GetString(SR.MenuAdapter_Expand, item.Text)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected virtual internal void RenderItem(HtmlTextWriter writer, MenuItem item, int position) {
|
||
|
Menu owner = Control;
|
||
|
MenuItemStyle mergedStyle = owner.GetMenuItemStyle(item);
|
||
|
|
||
|
string imageUrl = item.ImageUrl;
|
||
|
int depth = item.Depth;
|
||
|
int depthPlusOne = depth + 1;
|
||
|
string toolTip = item.ToolTip;
|
||
|
string navigateUrl = item.NavigateUrl;
|
||
|
string text = item.Text;
|
||
|
bool enabled = item.IsEnabled;
|
||
|
bool selectable = item.Selectable;
|
||
|
MenuItemCollection childItems = item.ChildItems;
|
||
|
|
||
|
// Top separator
|
||
|
string topSeparatorUrl = null;
|
||
|
if (depth < owner.StaticDisplayLevels && owner.StaticTopSeparatorImageUrl.Length != 0) {
|
||
|
topSeparatorUrl = owner.StaticTopSeparatorImageUrl;
|
||
|
}
|
||
|
else if (depth >= owner.StaticDisplayLevels && owner.DynamicTopSeparatorImageUrl.Length != 0) {
|
||
|
topSeparatorUrl = owner.DynamicTopSeparatorImageUrl;
|
||
|
}
|
||
|
if (topSeparatorUrl != null) {
|
||
|
Image separatorImage = new Image();
|
||
|
separatorImage.ImageUrl = topSeparatorUrl;
|
||
|
separatorImage.GenerateEmptyAlternateText = true; // XHtml compliance
|
||
|
separatorImage.Page = Page;
|
||
|
separatorImage.RenderControl(writer);
|
||
|
RenderBreak(writer);
|
||
|
}
|
||
|
|
||
|
// Don't render the top spacing if this is the first root item
|
||
|
if ((mergedStyle != null) && !mergedStyle.ItemSpacing.IsEmpty &&
|
||
|
((_titleItem != null) || (position != 0))) {
|
||
|
RenderSpace(writer, mergedStyle.ItemSpacing, owner.Orientation);
|
||
|
}
|
||
|
|
||
|
// Item span
|
||
|
Panel itemPanel = new SpanPanel();
|
||
|
itemPanel.Enabled = enabled;
|
||
|
itemPanel.Page = Page;
|
||
|
|
||
|
// Apply styles
|
||
|
if (Page != null && Page.SupportsStyleSheets) {
|
||
|
string styleClass = owner.GetCssClassName(item, false);
|
||
|
if (styleClass.Trim().Length > 0) {
|
||
|
itemPanel.CssClass = styleClass;
|
||
|
}
|
||
|
}
|
||
|
else if (mergedStyle != null) {
|
||
|
itemPanel.ApplyStyle(mergedStyle);
|
||
|
}
|
||
|
|
||
|
// Tooltip
|
||
|
if (item.ToolTip.Length != 0) {
|
||
|
itemPanel.ToolTip = item.ToolTip;
|
||
|
}
|
||
|
|
||
|
// Render item begin tag
|
||
|
itemPanel.RenderBeginTag(writer);
|
||
|
|
||
|
// If there is a navigation url on this item, set up the navigation stuff if:
|
||
|
// - the item is the current title item for this level
|
||
|
// - the item has no children
|
||
|
// - the item is a static item of depth + 1 < StaticDisplayLevels
|
||
|
bool clickOpensThisNode = !((position == 0) ||
|
||
|
(childItems.Count == 0) ||
|
||
|
(depthPlusOne < owner.StaticDisplayLevels) ||
|
||
|
(depthPlusOne >= owner.MaximumDepth));
|
||
|
|
||
|
// Indent
|
||
|
if (position != 0 &&
|
||
|
depth > 0 &&
|
||
|
owner.StaticSubMenuIndent != Unit.Pixel(0) &&
|
||
|
depth < owner.StaticDisplayLevels) {
|
||
|
Image spacerImage = new Image();
|
||
|
spacerImage.ImageUrl = owner.SpacerImageUrl;
|
||
|
spacerImage.GenerateEmptyAlternateText = true; // XHtml compliance
|
||
|
double indent = owner.StaticSubMenuIndent.Value * depth;
|
||
|
if (indent < Unit.MaxValue) {
|
||
|
spacerImage.Width = new Unit(indent, owner.StaticSubMenuIndent.Type);
|
||
|
}
|
||
|
else {
|
||
|
spacerImage.Width = new Unit(Unit.MaxValue, owner.StaticSubMenuIndent.Type);;
|
||
|
}
|
||
|
spacerImage.Height = Unit.Pixel(1);
|
||
|
spacerImage.Page = Page;
|
||
|
spacerImage.RenderControl(writer);
|
||
|
}
|
||
|
|
||
|
// Render out the item icon, if it is set and if the item is not templated (VSWhidbey 501618)
|
||
|
if (imageUrl.Length > 0 && item.NotTemplated()) {
|
||
|
Image newImage = new Image();
|
||
|
newImage.ImageUrl = imageUrl;
|
||
|
if (toolTip.Length != 0) {
|
||
|
newImage.AlternateText = toolTip;
|
||
|
}
|
||
|
else {
|
||
|
newImage.GenerateEmptyAlternateText = true; // XHtml compliance
|
||
|
}
|
||
|
newImage.Page = Page;
|
||
|
newImage.RenderControl(writer);
|
||
|
writer.Write(' ');
|
||
|
}
|
||
|
|
||
|
bool applyInlineBorder;
|
||
|
string linkClass;
|
||
|
if (Page != null && Page.SupportsStyleSheets) {
|
||
|
linkClass = owner.GetCssClassName(item, true, out applyInlineBorder);
|
||
|
}
|
||
|
else {
|
||
|
linkClass = String.Empty;
|
||
|
applyInlineBorder = false;
|
||
|
}
|
||
|
if (enabled && (clickOpensThisNode || selectable)) {
|
||
|
string accessKey = owner.AccessKey;
|
||
|
string itemAccessKey = ((position == 0 || (position == 1 && depth == 0)) && accessKey.Length != 0) ?
|
||
|
accessKey :
|
||
|
null;
|
||
|
if (navigateUrl.Length > 0 && !clickOpensThisNode) {
|
||
|
if (PageAdapter != null) {
|
||
|
PageAdapter.RenderBeginHyperlink(writer,
|
||
|
owner.ResolveClientUrl(navigateUrl),
|
||
|
true,
|
||
|
SR.GetString(SR.Adapter_GoLabel),
|
||
|
itemAccessKey != null ?
|
||
|
itemAccessKey :
|
||
|
(_currentAccessKey < 10 ?
|
||
|
(_currentAccessKey++).ToString(CultureInfo.InvariantCulture) :
|
||
|
null));
|
||
|
writer.Write(HttpUtility.HtmlEncode(item.FormattedText));
|
||
|
PageAdapter.RenderEndHyperlink(writer);
|
||
|
}
|
||
|
else {
|
||
|
HyperLink link = new HyperLink();
|
||
|
link.NavigateUrl = owner.ResolveClientUrl(navigateUrl);
|
||
|
string target = item.Target;
|
||
|
if (String.IsNullOrEmpty(target)) {
|
||
|
target = owner.Target;
|
||
|
}
|
||
|
if (!String.IsNullOrEmpty(target)) {
|
||
|
link.Target = target;
|
||
|
}
|
||
|
link.AccessKey = itemAccessKey;
|
||
|
link.Page = Page;
|
||
|
if (writer is Html32TextWriter) {
|
||
|
link.RenderBeginTag(writer);
|
||
|
SpanPanel lbl = new SpanPanel();
|
||
|
lbl.Page = Page;
|
||
|
RenderStyle(writer, lbl, linkClass, mergedStyle, applyInlineBorder);
|
||
|
lbl.RenderBeginTag(writer);
|
||
|
item.RenderText(writer);
|
||
|
lbl.RenderEndTag(writer);
|
||
|
link.RenderEndTag(writer);
|
||
|
}
|
||
|
else {
|
||
|
RenderStyle(writer, link, linkClass, mergedStyle, applyInlineBorder);
|
||
|
link.RenderBeginTag(writer);
|
||
|
item.RenderText(writer);
|
||
|
link.RenderEndTag(writer);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Otherwise, write out a postback that will open or select the item
|
||
|
else {
|
||
|
if (PageAdapter != null) {
|
||
|
PageAdapter.RenderPostBackEvent(writer,
|
||
|
owner.UniqueID,
|
||
|
(clickOpensThisNode ? 'o' : 'b') +
|
||
|
Escape(item.InternalValuePath),
|
||
|
SR.GetString(SR.Adapter_OKLabel),
|
||
|
item.FormattedText,
|
||
|
null,
|
||
|
itemAccessKey != null ?
|
||
|
itemAccessKey :
|
||
|
(_currentAccessKey < 10 ?
|
||
|
(_currentAccessKey++).ToString(CultureInfo.InvariantCulture) :
|
||
|
null));
|
||
|
|
||
|
// Expand image
|
||
|
if (clickOpensThisNode) {
|
||
|
RenderExpand(writer, item, owner);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
HyperLink link = new HyperLink();
|
||
|
link.NavigateUrl = Page.ClientScript.GetPostBackClientHyperlink(owner,
|
||
|
(clickOpensThisNode ? 'o' : 'b') + Escape(item.InternalValuePath), true);
|
||
|
link.AccessKey = itemAccessKey;
|
||
|
link.Page = Page;
|
||
|
if (writer is Html32TextWriter) {
|
||
|
link.RenderBeginTag(writer);
|
||
|
SpanPanel lbl = new SpanPanel();
|
||
|
lbl.Page = Page;
|
||
|
RenderStyle(writer, lbl, linkClass, mergedStyle, applyInlineBorder);
|
||
|
lbl.RenderBeginTag(writer);
|
||
|
item.RenderText(writer);
|
||
|
if (clickOpensThisNode) {
|
||
|
RenderExpand(writer, item, owner);
|
||
|
}
|
||
|
lbl.RenderEndTag(writer);
|
||
|
link.RenderEndTag(writer);
|
||
|
}
|
||
|
else {
|
||
|
RenderStyle(writer, link, linkClass, mergedStyle, applyInlineBorder);
|
||
|
link.RenderBeginTag(writer);
|
||
|
item.RenderText(writer);
|
||
|
if (clickOpensThisNode) {
|
||
|
RenderExpand(writer, item, owner);
|
||
|
}
|
||
|
link.RenderEndTag(writer);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
item.RenderText(writer);
|
||
|
}
|
||
|
itemPanel.RenderEndTag(writer);
|
||
|
|
||
|
// Bottom (or right) item spacing
|
||
|
RenderBreak(writer);
|
||
|
if ((mergedStyle != null) && !mergedStyle.ItemSpacing.IsEmpty) {
|
||
|
RenderSpace(writer, mergedStyle.ItemSpacing, owner.Orientation);
|
||
|
}
|
||
|
|
||
|
// Bottom separator
|
||
|
string bottomSeparatorUrl = null;
|
||
|
if (item.SeparatorImageUrl.Length != 0) {
|
||
|
bottomSeparatorUrl = item.SeparatorImageUrl;
|
||
|
}
|
||
|
else if ((depth < owner.StaticDisplayLevels) && (owner.StaticBottomSeparatorImageUrl.Length != 0)) {
|
||
|
bottomSeparatorUrl = owner.StaticBottomSeparatorImageUrl;
|
||
|
}
|
||
|
else if ((depth >= owner.StaticDisplayLevels) && (owner.DynamicBottomSeparatorImageUrl.Length != 0)) {
|
||
|
bottomSeparatorUrl = owner.DynamicBottomSeparatorImageUrl;
|
||
|
}
|
||
|
if (bottomSeparatorUrl != null) {
|
||
|
Image separatorImage = new Image();
|
||
|
separatorImage.ImageUrl = bottomSeparatorUrl;
|
||
|
separatorImage.GenerateEmptyAlternateText = true; // XHtml compliance
|
||
|
separatorImage.Page = Page;
|
||
|
separatorImage.RenderControl(writer);
|
||
|
RenderBreak(writer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderSpace(HtmlTextWriter writer, Unit space, Orientation orientation) {
|
||
|
Image spacerImage = new Image();
|
||
|
spacerImage.ImageUrl = Control.SpacerImageUrl;
|
||
|
spacerImage.GenerateEmptyAlternateText = true; // XHtml compliance
|
||
|
spacerImage.Page = Page;
|
||
|
if (orientation == Orientation.Vertical) {
|
||
|
spacerImage.Height = space;
|
||
|
spacerImage.Width = Unit.Pixel(1);
|
||
|
spacerImage.RenderControl(writer);
|
||
|
writer.WriteBreak();
|
||
|
}
|
||
|
else {
|
||
|
spacerImage.Width = space;
|
||
|
spacerImage.Height = Unit.Pixel(1);
|
||
|
spacerImage.RenderControl(writer);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RenderStyle(HtmlTextWriter writer, WebControl control, string className, MenuItemStyle style, bool applyInlineBorder) {
|
||
|
if (!String.IsNullOrEmpty(className)) {
|
||
|
control.CssClass = className;
|
||
|
if (applyInlineBorder) {
|
||
|
// Add inline style to force the border to none to override any CssClass (VSWhidbey 336610)
|
||
|
writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, "none");
|
||
|
// And an inline font-size of 1em to avoid squaring relative font sizes by applying them twice
|
||
|
writer.AddStyleAttribute(HtmlTextWriterStyle.FontSize, "1em");
|
||
|
}
|
||
|
}
|
||
|
else if (style != null) {
|
||
|
control.ApplyStyle(style);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
|
||
|
RaisePostBackEvent(eventArgument);
|
||
|
}
|
||
|
|
||
|
protected virtual void RaisePostBackEvent(string eventArgument) {
|
||
|
if (eventArgument.Length == 0) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// On postback, see what kind of event we received by checking the first character
|
||
|
char eventType = eventArgument[0];
|
||
|
|
||
|
switch (eventType) {
|
||
|
case 'o': {
|
||
|
// 'o' means that we're opening the secondary navigation for this node
|
||
|
// Get the path of the item specified in the eventArgument
|
||
|
// The replace is to correct a Netscape 4 bug
|
||
|
string newPath = UnEscape(HttpUtility.UrlDecode(eventArgument.Substring(1)));
|
||
|
// Check the number of separator characters in the argument (should not be more than the max depth)
|
||
|
int matches = 0;
|
||
|
for (int i = 0; i < newPath.Length; i++) {
|
||
|
if (newPath[i] == TreeView.InternalPathSeparator) {
|
||
|
if (++matches >= Control.MaximumDepth) {
|
||
|
throw new InvalidOperationException(SR.GetString(SR.Menu_InvalidDepth));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Check this item does have subitem
|
||
|
// (otherwise, it should just be selected, not opened)
|
||
|
MenuItem item = Control.Items.FindItem(newPath.Split(TreeView.InternalPathSeparator), 0);
|
||
|
if (item != null) {
|
||
|
if (item.ChildItems.Count > 0) {
|
||
|
_path = newPath;
|
||
|
}
|
||
|
else {
|
||
|
Control.InternalRaisePostBackEvent(newPath);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
case 'u' :
|
||
|
// 'u' means go up a level
|
||
|
if (_path != null) {
|
||
|
// Find that item in the tree
|
||
|
MenuItem item = Control.Items.FindItem(_path.Split(TreeView.InternalPathSeparator), 0);
|
||
|
if (item != null) {
|
||
|
MenuItem parentItem = item.Parent;
|
||
|
if (parentItem != null && item.Depth + 1 > Control.StaticDisplayLevels) {
|
||
|
_path = parentItem.InternalValuePath;
|
||
|
}
|
||
|
else {
|
||
|
_path = null;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case 'b' :
|
||
|
// 'b' means bubble for to the control to handle
|
||
|
// The replace is to correct a Netscape 4 bug
|
||
|
Control.InternalRaisePostBackEvent(
|
||
|
UnEscape(HttpUtility.UrlDecode(eventArgument.Substring(1))));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal void SetPath(string path) {
|
||
|
_path = path;
|
||
|
}
|
||
|
|
||
|
private class SpanPanel : Panel {
|
||
|
protected override HtmlTextWriterTag TagKey {
|
||
|
get {
|
||
|
return HtmlTextWriterTag.Span;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|