// // System.Web.UI.WebControls.MenuItem.cs // // Authors: // Lluis Sanchez Gual (lluis@novell.com) // // (C) 2004 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) 2004 Novell, Inc (http://www.novell.com) // #if NET_2_0 using System; using System.Collections; using System.Text; using System.ComponentModel; using System.Web.UI; namespace System.Web.UI.WebControls { [ParseChildrenAttribute (true, "ChildItems")] public sealed class MenuItem: IStateManager, ICloneable { StateBag ViewState = new StateBag (); MenuItemCollection items; bool marked; Menu menu; MenuItem parent; int index; string path; int depth = -1; object dataItem; IHierarchyData hierarchyData; bool gotBinding; MenuItemBinding binding; PropertyDescriptorCollection boundProperties; public MenuItem () { } public MenuItem (string text) { Text = text; } public MenuItem (string text, string value) { Text = text; Value = value; } public MenuItem (string text, string value, string imageUrl) { Text = text; Value = value; ImageUrl = imageUrl; } public MenuItem (string text, string value, string imageUrl, string navigateUrl) { Text = text; Value = value; ImageUrl = imageUrl; NavigateUrl = navigateUrl; } public MenuItem (string text, string value, string imageUrl, string navigateUrl, string target) { Text = text; Value = value; ImageUrl = imageUrl; NavigateUrl = navigateUrl; Target = target; } [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] [Browsable (false)] public int Depth { get { if (depth != -1) return depth; if (Parent == null) depth = 0; else depth = Parent.Depth + 1; return depth; } } void ResetPathData () { path = null; depth = -1; gotBinding = false; } internal Menu Menu { get { return menu; } set { menu = value; if (items != null) items.SetMenu (menu); ResetPathData (); } } [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] [DefaultValue (false)] [Browsable (false)] public bool DataBound { get { return ViewState ["DataBound"] == null ? false : (bool) ViewState ["DataBound"]; } private set { ViewState ["DataBound"] = value; } } [DefaultValue (null)] [Browsable (false)] public object DataItem { get { if (!DataBound) throw new InvalidOperationException ("MenuItem is not data bound."); return dataItem; } } [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] [DefaultValue ("")] [Browsable (false)] public string DataPath { get { return ViewState ["DataPath"] == null ? String.Empty : (String) ViewState ["DataPath"]; } private set { ViewState ["DataPath"] = value; } } [MergableProperty (false)] [Browsable (false)] [PersistenceMode (PersistenceMode.InnerDefaultProperty)] public MenuItemCollection ChildItems { get { if (items == null) { items = new MenuItemCollection (this); if (((IStateManager)this).IsTrackingViewState) ((IStateManager)items).TrackViewState(); } return items; } } [DefaultValue ("")] [UrlProperty] [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] public string ImageUrl { get { return ViewState ["ImageUrl"] == null ? String.Empty : (String) ViewState ["ImageUrl"]; } set { ViewState ["ImageUrl"] = value; } } [DefaultValue ("")] [UrlProperty] [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] public string NavigateUrl { get { return ViewState ["NavigateUrl"] == null ? String.Empty : (String) ViewState ["NavigateUrl"]; } set { ViewState ["NavigateUrl"] = value; } } [DefaultValue ("")] [UrlProperty] [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] public string PopOutImageUrl { get { return ViewState ["PopOutImageUrl"] == null ? String.Empty : (String) ViewState ["PopOutImageUrl"]; } set { ViewState ["PopOutImageUrl"] = value; } } [DefaultValue ("")] public string Target { get { return ViewState ["Target"] == null ? String.Empty : (String) ViewState ["Target"]; } set { ViewState ["Target"] = value; } } [Localizable (true)] [DefaultValue ("")] public string Text { get { object o = ViewState ["Text"]; if (o == null) o = ViewState ["Value"]; if (o != null) return (string) o; return String.Empty; } set { ViewState ["Text"] = value; } } [Localizable (true)] [DefaultValue ("")] public string ToolTip { get { return ViewState ["ToolTip"] == null ? String.Empty : (String) ViewState ["ToolTip"]; } set { ViewState ["ToolTip"] = value; } } [Localizable (true)] [DefaultValue ("")] public string Value { get { object o = ViewState ["Value"]; if (o == null) o = ViewState ["Text"]; if (o != null) return (string) o; return String.Empty; } set { ViewState ["Value"] = value; } } [DefaultValue ("")] [UrlProperty] [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))] public string SeparatorImageUrl { get { return ViewState ["SeparatorImageUrl"] == null ? String.Empty : (String) ViewState ["SeparatorImageUrl"]; } set { ViewState ["SeparatorImageUrl"] = value; } } [BrowsableAttribute (true)] [DefaultValueAttribute (true)] public bool Selectable { get { return ViewState ["Selectable"] == null ? true : (bool) ViewState ["Selectable"]; } set { ViewState ["Selectable"] = value; } } [BrowsableAttribute (true)] [DefaultValueAttribute (true)] public bool Enabled { get { return ViewState ["Enabled"] == null ? true : (bool) ViewState ["Enabled"]; } set { ViewState ["Enabled"] = value; } } internal bool BranchEnabled { get { return Enabled && (parent == null || parent.BranchEnabled); } } [DefaultValue (false)] [Browsable (true)] public bool Selected { get { if (menu != null) return menu.SelectedItem == this; else return false; } set { if (menu != null) { if (!value && menu.SelectedItem == this) menu.SetSelectedItem (null); else if (value) menu.SetSelectedItem (this); } } } [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] [Browsable (false)] public MenuItem Parent { get { return parent; } } [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] [Browsable (false)] public string ValuePath { get { if (menu == null) return Value; StringBuilder sb = new StringBuilder (Value); MenuItem item = parent; while (item != null) { sb.Insert (0, menu.PathSeparator); sb.Insert (0, item.Value); item = item.Parent; } return sb.ToString (); } } internal int Index { get { return index; } set { index = value; ResetPathData (); } } internal void SetParent (MenuItem item) { parent = item; ResetPathData (); } internal string Path { get { if (path != null) return path; StringBuilder sb = new StringBuilder (index.ToString()); MenuItem item = parent; while (item != null) { sb.Insert (0, '_'); sb.Insert (0, item.Index.ToString ()); item = item.Parent; } path = sb.ToString (); return path; } } internal bool HasChildData { get { return items != null; } } void IStateManager.LoadViewState (object savedState) { if (savedState == null) return; object[] states = (object[]) savedState; ViewState.LoadViewState (states [0]); if (states [1] != null) ((IStateManager)ChildItems).LoadViewState (states [1]); } object IStateManager.SaveViewState () { object[] states = new object[2]; states[0] = ViewState.SaveViewState(); states[1] = (items == null ? null : ((IStateManager)items).SaveViewState()); for (int i = 0; i < states.Length; i++) { if (states [i] != null) return states; } return null; } void IStateManager.TrackViewState () { if (marked) return; marked = true; ViewState.TrackViewState(); if (items != null) ((IStateManager)items).TrackViewState (); } bool IStateManager.IsTrackingViewState { get { return marked; } } internal void SetDirty () { ViewState.SetDirty (true); if (items != null) items.SetDirty (); } object ICloneable.Clone () { MenuItem nod = new MenuItem (); foreach (DictionaryEntry e in ViewState) nod.ViewState [(string)e.Key] = e.Value; foreach (ICloneable c in ChildItems) nod.ChildItems.Add ((MenuItem)c.Clone ()); return nod; } internal void Bind (IHierarchyData hierarchyData) { this.hierarchyData = hierarchyData; DataBound = true; DataPath = hierarchyData.Path; dataItem = hierarchyData.Item; MenuItemBinding bin = GetBinding (); if (bin != null) { // Bind Enabled property if (bin.EnabledField != "") try { Enabled = Convert.ToBoolean (GetBoundPropertyValue (bin.EnabledField)); } catch { Enabled = bin.Enabled; } else Enabled = bin.Enabled; // Bind ImageUrl property if (bin.ImageUrlField.Length > 0) { ImageUrl = Convert.ToString (GetBoundPropertyValue (bin.ImageUrlField)); if (ImageUrl.Length == 0) ImageUrl = bin.ImageUrl; } else if (bin.ImageUrl.Length > 0) ImageUrl = bin.ImageUrl; // Bind NavigateUrl property if (bin.NavigateUrlField.Length > 0) { NavigateUrl = Convert.ToString (GetBoundPropertyValue (bin.NavigateUrlField)); if (NavigateUrl.Length == 0) NavigateUrl = bin.NavigateUrl; } else if (bin.NavigateUrl.Length > 0) NavigateUrl = bin.NavigateUrl; // Bind PopOutImageUrl property if (bin.PopOutImageUrlField.Length > 0) { PopOutImageUrl = Convert.ToString (GetBoundPropertyValue (bin.PopOutImageUrlField)); if (PopOutImageUrl.Length == 0) PopOutImageUrl = bin.PopOutImageUrl; } else if (bin.PopOutImageUrl.Length > 0) PopOutImageUrl = bin.PopOutImageUrl; // Bind Selectable property if (bin.SelectableField != "") try { Selectable = Convert.ToBoolean (GetBoundPropertyValue (bin.SelectableField)); } catch { Selectable = bin.Selectable; } else Selectable = bin.Selectable; // Bind SeparatorImageUrl property if (bin.SeparatorImageUrlField.Length > 0) { SeparatorImageUrl = Convert.ToString (GetBoundPropertyValue (bin.SeparatorImageUrlField)); if (SeparatorImageUrl.Length == 0) SeparatorImageUrl = bin.SeparatorImageUrl; } else if (bin.SeparatorImageUrl.Length > 0) SeparatorImageUrl = bin.SeparatorImageUrl; // Bind Target property if (bin.TargetField.Length > 0) { Target = Convert.ToString (GetBoundPropertyValue (bin.TargetField)); if (Target.Length == 0) Target = bin.Target; } else if (bin.Target.Length > 0) Target = bin.Target; // Bind ToolTip property if (bin.ToolTipField.Length > 0) { ToolTip = Convert.ToString (GetBoundPropertyValue (bin.ToolTipField)); if (ToolTip.Length == 0) ToolTip = bin.ToolTip; } else if (bin.ToolTip.Length > 0) ToolTip = bin.ToolTip; // Bind Value property string value = null; if (bin.ValueField.Length > 0) { value = Convert.ToString (GetBoundPropertyValue (bin.ValueField)); } if (String.IsNullOrEmpty (value)) { if (bin.Value.Length > 0) value = bin.Value; else if (bin.Text.Length > 0) value = bin.Text; else value = String.Empty; } Value = value; // Bind Text property string text = null; if (bin.TextField.Length > 0) { text = Convert.ToString (GetBoundPropertyValue (bin.TextField)); if (bin.FormatString.Length > 0) text = string.Format (bin.FormatString, text); } if (String.IsNullOrEmpty (text)) { if (bin.Text.Length > 0) text = bin.Text; else if (bin.Value.Length > 0) text = bin.Value; else text = String.Empty; } Text = text; } else { Text = Value = GetDefaultBoundText (); } INavigateUIData navigateUIData = hierarchyData as INavigateUIData; if (navigateUIData != null) { ToolTip = navigateUIData.Description; Text = navigateUIData.ToString (); NavigateUrl = navigateUIData.NavigateUrl; } } internal void SetDataItem (object item) { dataItem = item; } internal void SetDataPath (string path) { DataPath = path; } internal void SetDataBound (bool bound) { DataBound = bound; } string GetDefaultBoundText () { if (hierarchyData != null) return hierarchyData.ToString (); else if (dataItem != null) return dataItem.ToString (); else return string.Empty; } string GetDataItemType () { if (hierarchyData != null) return hierarchyData.Type; else if (dataItem != null) return dataItem.GetType().ToString (); else return string.Empty; } MenuItemBinding GetBinding () { if (menu == null) return null; if (gotBinding) return binding; binding = menu.FindBindingForItem (GetDataItemType (), Depth); gotBinding = true; return binding; } object GetBoundPropertyValue (string name) { if (boundProperties == null) { if (hierarchyData != null) boundProperties = TypeDescriptor.GetProperties (hierarchyData); else boundProperties = TypeDescriptor.GetProperties (dataItem); } PropertyDescriptor prop = boundProperties.Find (name, true); if (prop == null) throw new InvalidOperationException ("Property '" + name + "' not found in data bound item"); if (hierarchyData != null) return prop.GetValue (hierarchyData); else return prop.GetValue (dataItem); } } } #endif