|
// MenuLink.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Drawing;
using System.Globalization;
using System.Security.Permissions;
namespace mtweb
{
//////////////////////////////////////////////////////////////////////////
// LinkButtonEx
public class LinkButtonEx : LinkButton
{
// Fields
private MenuLink ml = null;
// Constructor
public LinkButtonEx(MenuLink link) : base()
{
if (link == null) {
string err = "LinkButtonEx: MenuLink is null.";
throw new Exception(err);
}
this.ml = link;
}
///////////////////////////////////////////////
// Events
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// Parent must be MenuLink
if (!(this.Parent is MenuLink)) {
string err = "LinkButtonEx: parent is not MenuLink.";
throw new Exception(err);
}
}
///////////////////////////////////////////////
// Rendering
public override void RenderBeginTag(HtmlTextWriter writer)
{
base.RenderBeginTag(writer);
}
// Note: don't call base, set attributes manually
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
// The menu
AMenu menu = ml.GetMenu();
if (menu == null) {
string err = "LinkButtonEx: Menu is null.";
throw new Exception(err);
}
// ID
writer.AddAttribute("id", this.ClientID);
// The HREF script, initally NOP
string s = "javascript:void(0)";
// HREF will be one of the following sctipts:
//
// [1] If this.PostBackUrl is empty:
//
// __doPostBack(eventTarget, eventArgument)
//
// [2] If this.PostBackUrl is not empty:
//
// WebForm_DoPostBackWithOptions(new
// WebForm_PostBackOptions(eventTarget, eventArgument,
// validation, validationGroup,
// actionUrl,
// trackFocus, clientSubmit)
// )
if (ml.Enabled && (!string.IsNullOrEmpty(CommandName) ||
!string.IsNullOrEmpty(PostBackUrl)))
{
string url = AMenu.ToAbsolute(PostBackUrl);
PostBackOptions opt = new PostBackOptions(this);
opt.Argument = ""; // eventArgument
opt.PerformValidation = false; // validation
opt.ValidationGroup = ""; // validationGroup
opt.ActionUrl = url; // actionUrl
opt.TrackFocus = false; // trackFocus
opt.ClientSubmit = true; // clientSubmit
opt.AutoPostBack = false;
opt.RequiresJavaScriptProtocol = true;
s = Page.ClientScript.GetPostBackEventReference(opt);
}
// HREF
writer.AddAttribute("href", s);
// Client side click
if (!string.IsNullOrEmpty(OnClientClick)) {
writer.AddAttribute("onclick", OnClientClick);
}
// Icon image (as background)
if (!string.IsNullOrEmpty(ml.IconImage)) {
string url = "url(" + ml.IconImage + ")";
writer.AddStyleAttribute("background-image", url);
}
// Foreground color
if (!menu.ForeColor.IsEmpty) {
string fore_color = ColorTranslator.ToHtml(menu.ForeColor);
if (!AMenu.IsDefault(fore_color, AMenu.DEF_FORECOLOR)) {
writer.AddStyleAttribute("color", fore_color);
}
}
// Width
if (!ml.Width_A.IsEmpty) {
writer.AddStyleAttribute("width", ml.Width_A.ToString());
}
// No margin if top-menu has no border
if (ml.IsTopLink && !menu.Border) {
writer.AddStyleAttribute("margin", "0");
}
}
public override void RenderEndTag(HtmlTextWriter writer)
{
if (ml.IsParent) writer.Write("<!--[if gte IE 7]><!-->");
base.RenderEndTag(writer);
if (ml.IsParent) writer.Write("<!--<![endif]-->");
}
} // class
//////////////////////////////////////////////////////////////////////////
// MenuLink
[ParseChildren(false)]
[PersistChildren(true)]
[DefaultProperty("Text")]
[DefaultEvent("Click")]
[ToolboxData("<{0}:MenuLink runat=server></{0}:MenuLink>")]
public class MenuLink : WebControl, INamingContainer
{
// Fields
private LinkButtonEx m_lb = null; // our LinkButton
private ArrayList m_Items = new ArrayList(); // child controls
private event CommandEventHandler m_ItemClick; // click handler
// Constructor
public MenuLink() : base(HtmlTextWriterTag.Li)
{
}
///////////////////////////////////////////////
// Events
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// Parent must be AMenu or AMenuSub
if (!(this.Parent is AMenu) && !(this.Parent is AMenuSub))
{
string err = "MenuLink: parent is not AMenu or AMenuSub.";
throw new Exception(err);
}
// Create the LinkButton
m_lb = new LinkButtonEx(this);
m_lb.ID = "LB";
m_lb.Text = this.Text;
m_lb.CommandName = this.CommandName;
m_lb.CommandArgument = this.CommandArgument;
m_lb.PostBackUrl = this.PostBackUrl;
m_lb.OnClientClick = this.OnClientClick;
this.Controls.Add(m_lb);
// Initialize:
// - determine and save the IsParent property
// - determine and save the IsTopLink property
// - calculate and save the width of <A> elements
//
Initialize();
}
///////////////////////////////////////////////
// Properties
// Hide inherited:
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Unit Height
{
get { return Unit.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Unit Width
{
get { return Unit.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Color ForeColor
{
get { return Color.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Color BackColor
{
get { return Color.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Color BorderColor
{
get { return Color.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Unit BorderWidth
{
get { return Unit.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override BorderStyle BorderStyle
{
get { return BorderStyle.NotSet;}
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override FontInfo Font
{
get { return null;}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override String SkinID
{
get { return string.Empty; }
set {}
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override Boolean EnableTheming
{
get { return false; }
set {}
}
// MenuLink:
// Child controls
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ArrayList Items
{
get { return m_Items; }
set { m_Items = value;}
}
// Text
[Category("Appearance")]
[DefaultValue("")]
[Bindable(true)]
public string Text
{
get {
String s = (String)ViewState["Text"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["Text"] = value;
}
}
// IconImage
[Category("Appearance")]
[UrlProperty()]
[DefaultValue(AMenu.DEF_ICONIMAGE)]
[Bindable(true)]
public virtual string IconImage
{
get {
String s = (String)ViewState["IconImage"];
if (s == null) s = AMenu.DEF_ICONIMAGE;
return AMenu.ToAbsolute(s);
}
set {
ViewState["IconImage"] = value;
}
}
// CommandName
[Category("Behavior")]
[DefaultValue("")]
[Bindable(true)]
public virtual string CommandName
{
get {
String s = (String)ViewState["CommandName"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["CommandName"] = value;
}
}
// CommandArgument
[Category("Behavior")]
[DefaultValue("")]
[Bindable(true)]
public virtual string CommandArgument
{
get {
String s = (String)ViewState["CommandArgument"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["CommandArgument"] = value;
}
}
// PostBackUrl
[Category("Behavior")]
[DefaultValue("")]
[Bindable(true)]
public virtual string PostBackUrl
{
get {
String s = (String)ViewState["PostBackUrl"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["PostBackUrl"] = value;
}
}
// ToolTip
[Category("Behavior")]
[DefaultValue("")]
[Bindable(true)]
public override string ToolTip
{
get {
String s = (String)ViewState["LinkToolTip"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["LinkToolTip"] = value;
}
}
// IsParent
[ReadOnly(true)]
[Browsable(false)]
[DefaultValue(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool IsParent
{
get {
object o = ViewState["IsParent"];
return (o == null) ? false : (bool)o;
}
set {
ViewState["IsParent"] = value;
}
}
// IsTopLink
[ReadOnly(true)]
[Browsable(false)]
[DefaultValue(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual bool IsTopLink
{
get {
object o = ViewState["IsTopLink"];
return (o == null) ? false : (bool)o;
}
set {
ViewState["IsTopLink"] = value;
}
}
// Width_A
[ReadOnly(true)]
[Browsable(false)]
[DefaultValue(typeof(Unit),"0")]
[TypeConverter(typeof(UnitConverter))]
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual Unit Width_A
{
get {
object o = ViewState["Width_A"];
if (o != null && ((Unit)o) != Unit.Empty) return (Unit)o;
return Unit.Empty;
}
set {
ViewState["Width_A"] = value;
}
}
// Click handler (server)
[Category("Action")]
public event CommandEventHandler Click
{
add { m_ItemClick += value; }
remove { m_ItemClick -= value; }
}
// Click handler (client)
[Category("Behavior")]
public string OnClientClick
{
get {
String s = (String)ViewState["OnClientClick"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["OnClientClick"] = value;
}
}
///////////////////////////////////////////////
// Rendering
public override void RenderBeginTag(HtmlTextWriter writer)
{
base.RenderBeginTag(writer);
}
// Note: don't call base, set attributes manually
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
// The menu
AMenu menu = GetMenu();
if (menu == null) {
string err = "MenuLink: Menu is null.";
throw new Exception(err);
}
// ID
writer.AddAttribute("id", this.ClientID);
// ToolTip
if (!string.IsNullOrEmpty(ToolTip)) {
writer.AddAttribute("title", ToolTip);
}
// Border (left/right) color
if (!menu.BorderColor.IsEmpty) {
string borderc = ColorTranslator.ToHtml(menu.BorderColor);
if (!AMenu.IsDefault(borderc, AMenu.DEF_BORDERCOLOR)) {
writer.AddStyleAttribute("border-color", borderc);
}
}
// Remove top-menu borders (left/right), if needed
if (IsTopLink && !menu.Border) {
writer.AddStyleAttribute("border", "none");
}
// Color codes
string fc="", bc="", fh="", bh="";
if (!menu.ForeColor.IsEmpty) {
fc = "'" + ColorTranslator.ToHtml(menu.ForeColor) + "'";
}
if (!menu.BackColor.IsEmpty) {
bc = "'" + ColorTranslator.ToHtml(menu.BackColor) + "'";
}
if (!menu.ForeHover.IsEmpty) {
fh = "'" + ColorTranslator.ToHtml(menu.ForeHover) + "'";
}
if (!menu.BackHover.IsEmpty) {
bh = "'" + ColorTranslator.ToHtml(menu.BackHover) + "'";
}
// Our LinkButton
string id = "'" + m_lb.ClientID + "'";
// Hover colors (set on the link element)
if (this.Enabled)
{
// True if hover color has been set
bool bHoverSet = false;
// Set hover colors
string s = "";
if (!string.IsNullOrEmpty(fh) && !string.IsNullOrEmpty(fc)) {
if (!AMenu.IsDefault(fh, AMenu.DEF_FOREHOVER)) {
s += "getElementById(" + id + ").style.color=" + fh + ";";
}
}
if (!string.IsNullOrEmpty(bh) && !string.IsNullOrEmpty(bc)) {
if (!AMenu.IsDefault(bh, AMenu.DEF_BACKHOVER)) {
s += "getElementById(" + id + ").style.backgroundColor=" + bh + ";";
}
}
if (!string.IsNullOrEmpty(s)) {
writer.AddAttribute("onmouseover", s);
bHoverSet = true;
}
// Reset hover colors
if (bHoverSet)
{
s = "";
if (!string.IsNullOrEmpty(fc)) {
s += "getElementById(" + id + ").style.color=" + fc + ";";
}
if (!string.IsNullOrEmpty(bc)) {
s += "getElementById(" + id + ").style.backgroundColor=" + bc + ";";
}
if (!string.IsNullOrEmpty(s)) {
writer.AddAttribute("onmouseout", s);
}
}
}
// Disabled - override CSS hover colors
else
{
string s = "";
if (!string.IsNullOrEmpty(fc)) {
s += "getElementById(" + id + ").style.color=" + fc + ";";
}
if (!string.IsNullOrEmpty(bc)) {
s += "getElementById(" + id + ").style.backgroundColor=" + bc + ";";
}
if (!string.IsNullOrEmpty(s)) {
writer.AddAttribute("onmouseover", s);
}
}
}
public override void RenderEndTag(HtmlTextWriter writer)
{
base.RenderEndTag(writer);
}
///////////////////////////////////////////////
// Methods
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void AddParsedSubObject(Object obj)
{
if (!Enabled) return;
m_Items.Add(obj);
}
protected override void CreateChildControls()
{
foreach (Control c in m_Items) {
this.Controls.Add(c);
}
}
// Return TRUE if event should not be bubbled
protected override bool OnBubbleEvent(object sender, EventArgs e)
{
// If we are disabled, just ignore
if (!Enabled) return true;
// If not a command arg, or not from LinkButtonEx, pass on
if (!(e is CommandEventArgs) || !(sender is LinkButtonEx))
{
return false;
}
// Call the handler if we got one
if (m_ItemClick != null) {
m_ItemClick(this, (CommandEventArgs)e);
return true;
}
// Bubble to AMenu using 'this' as sender
RaiseBubbleEvent(this, e);
return true;
}
///////////////////////////////////////////////
// Utility
//
public AMenu GetMenu()
{
Control c = this;
while (c != null)
{
c = c.Parent;
if (c is AMenu) return (AMenu)c;
}
return null; // error
}
//
public AMenuSub GetSubMenu()
{
if (!(Parent is AMenuSub)) return null;
return (AMenuSub)Parent;
}
//
protected void Initialize()
{
// Determine if we are Parent
foreach (Control c in m_Items) {
if (c is AMenuSub) {IsParent = true; break;}
}
// Determine if we are a top-menu link
IsTopLink = (Parent is AMenu);
// Calculate and save layout
SaveLayout();
}
// Calculate and save the width of <A> elements
protected void SaveLayout()
{
// Local variables
double width_li = 0; // width of the LI element
double width_a = 0; // width of the A element
double margin = 0; // left and right margins
double padding = 0; // left padding (indent)
double font_size = 0; // font size
// Get parent top-menu
AMenu top = GetMenu();
if (top == null) return; // error
// Current font size. Only PX accepted
if (!top.FontSize.IsEmpty && top.FontSize.Type == UnitType.Pixel) {
font_size = top.FontSize.Value;
}
else {
font_size = (Unit.Parse(AMenu.DEF_FONTSIZE)).Value;
}
// [1] If we are a top-menu link:
if (this.IsTopLink)
{
// If 'Width' is missing, just return
if (top.Width.IsEmpty) return;
// We only accept PX and EM. No euros here, pal.
if (top.Width.Type != UnitType.Pixel &&
top.Width.Type != UnitType.Em)
{
return;
}
// Width, margin and padding
width_li = top.Width.Value;
margin = top.Margin.Value;
padding = top.Indent.Value;
// Remove margin if top menu has no border
if (!top.Border) margin = 0;
// Convert margin/padding to EM, if needed
if (top.Width.Type == UnitType.Em) {
if (font_size == 0) font_size = 12; // def
margin = margin / font_size;
padding = padding / font_size;
}
// Calculate width_a
width_a = width_li - ((2 * margin) + padding);
if (width_a <= 0) width_a = width_li;
// Convert to Units and save
if (top.Width.Type == UnitType.Em) {
this.Width_A = Unit.Parse(width_a.ToString() + "em");
}
else {
this.Width_A = Unit.Parse(width_a.ToString() + "px");
}
return;
}
// [2] We are a sub-menu link:
// Get parent sub-menu
AMenuSub sub = GetSubMenu();
if (sub == null) return; // error
// If new 'Width' is not set, just return
if (sub.Width.IsEmpty) return;
// We only accept PX and EM
if (sub.Width.Type != UnitType.Pixel &&
sub.Width.Type != UnitType.Em)
{
return;
}
// Width, margin and padding
width_li = sub.Width.Value;
margin = sub.Margin.Value;
padding = sub.Indent.Value;
// Convert margin/padding to EM, if needed
if (sub.Width.Type == UnitType.Em) {
if (font_size == 0) font_size = 12; // def
margin = margin / font_size;
padding = padding / font_size;
}
// Calculate width_a
width_a = width_li - ((2 * margin) + padding);
if (width_a <= 0) width_a = width_li;
// Convert to Units and save
if (sub.Width.Type == UnitType.Em) {
this.Width_A = Unit.Parse(width_a.ToString() + "em");
}
else {
this.Width_A = Unit.Parse(width_a.ToString() + "px");
}
}
} // class
} // namespace
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.