3c1f479b9d
Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
617 lines
15 KiB
C#
617 lines
15 KiB
C#
//
|
|
// 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)
|
|
//
|
|
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|