2 // System.Web.UI.WebControls.MenuItem.cs
5 // Lluis Sanchez Gual (lluis@novell.com)
7 // (C) 2004 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
34 using System.Collections;
36 using System.ComponentModel;
39 namespace System.Web.UI.WebControls
41 [ParseChildrenAttribute (true, "ChildItems")]
42 public sealed class MenuItem: IStateManager, ICloneable
44 StateBag ViewState = new StateBag ();
45 MenuItemCollection items;
54 IHierarchyData hierarchyData;
57 MenuItemBinding binding;
58 PropertyDescriptorCollection boundProperties;
64 public MenuItem (string text)
69 public MenuItem (string text, string value)
75 public MenuItem (string text, string value, string imageUrl)
82 public MenuItem (string text, string value, string imageUrl, string navigateUrl)
87 NavigateUrl = navigateUrl;
90 public MenuItem (string text, string value, string imageUrl, string navigateUrl, string target)
95 NavigateUrl = navigateUrl;
99 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
103 if (depth != -1) return depth;
104 if (Parent == null) depth = 0;
105 else depth = Parent.Depth + 1;
110 void ResetPathData ()
122 items.SetMenu (menu);
127 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
128 [DefaultValue (false)]
130 public bool DataBound {
131 get { return ViewState ["DataBound"] == null ? false : (bool) ViewState ["DataBound"]; }
132 private set { ViewState ["DataBound"] = value; }
135 [DefaultValue (null)]
137 public object DataItem {
139 if (!DataBound) throw new InvalidOperationException ("MenuItem is not data bound.");
144 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
147 public string DataPath {
149 return ViewState ["DataPath"] == null ? String.Empty : (String) ViewState ["DataPath"];
152 ViewState ["DataPath"] = value;
156 [MergableProperty (false)]
158 [PersistenceMode (PersistenceMode.InnerDefaultProperty)]
159 public MenuItemCollection ChildItems {
162 items = new MenuItemCollection (this);
164 if (((IStateManager)this).IsTrackingViewState)
165 ((IStateManager)items).TrackViewState();
173 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
174 public string ImageUrl {
176 return ViewState ["ImageUrl"] == null ? String.Empty : (String) ViewState ["ImageUrl"];
179 ViewState ["ImageUrl"] = value;
185 [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
186 public string NavigateUrl {
188 return ViewState ["NavigateUrl"] == null ? String.Empty : (String) ViewState ["NavigateUrl"];
191 ViewState ["NavigateUrl"] = value;
197 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
198 public string PopOutImageUrl {
200 return ViewState ["PopOutImageUrl"] == null ? String.Empty : (String) ViewState ["PopOutImageUrl"];
203 ViewState ["PopOutImageUrl"] = value;
208 public string Target {
210 return ViewState ["Target"] == null ? String.Empty : (String) ViewState ["Target"];
213 ViewState ["Target"] = value;
221 object o = ViewState ["Text"];
223 o = ViewState ["Value"];
229 ViewState ["Text"] = value;
235 public string ToolTip {
237 return ViewState ["ToolTip"] == null ? String.Empty : (String) ViewState ["ToolTip"];
240 ViewState ["ToolTip"] = value;
246 public string Value {
248 object o = ViewState ["Value"];
250 o = ViewState ["Text"];
256 ViewState ["Value"] = value;
262 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
263 public string SeparatorImageUrl {
265 return ViewState ["SeparatorImageUrl"] == null ? String.Empty : (String) ViewState ["SeparatorImageUrl"];
268 ViewState ["SeparatorImageUrl"] = value;
272 [BrowsableAttribute (true)]
273 [DefaultValueAttribute (true)]
274 public bool Selectable {
276 return ViewState ["Selectable"] == null ? true : (bool) ViewState ["Selectable"];
279 ViewState ["Selectable"] = value;
283 [BrowsableAttribute (true)]
284 [DefaultValueAttribute (true)]
285 public bool Enabled {
287 return ViewState ["Enabled"] == null ? true : (bool) ViewState ["Enabled"];
290 ViewState ["Enabled"] = value;
294 internal bool BranchEnabled {
295 get { return Enabled && (parent == null || parent.BranchEnabled); }
298 [DefaultValue (false)]
300 public bool Selected {
303 return menu.SelectedItem == this;
309 if (!value && menu.SelectedItem == this)
310 menu.SetSelectedItem (null);
312 menu.SetSelectedItem (this);
317 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
319 public MenuItem Parent {
320 get { return parent; }
323 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
325 public string ValuePath {
327 if (menu == null) return Value;
329 StringBuilder sb = new StringBuilder (Value);
330 MenuItem item = parent;
331 while (item != null) {
332 sb.Insert (0, menu.PathSeparator);
333 sb.Insert (0, item.Value);
336 return sb.ToString ();
341 get { return index; }
342 set { index = value; ResetPathData (); }
345 internal void SetParent (MenuItem item) {
350 internal string Path {
352 if (path != null) return path;
353 StringBuilder sb = new StringBuilder (index.ToString());
354 MenuItem item = parent;
355 while (item != null) {
357 sb.Insert (0, item.Index.ToString ());
360 path = sb.ToString ();
365 internal bool HasChildData {
366 get { return items != null; }
369 void IStateManager.LoadViewState (object savedState)
371 if (savedState == null)
374 object[] states = (object[]) savedState;
375 ViewState.LoadViewState (states [0]);
377 if (states [1] != null)
378 ((IStateManager)ChildItems).LoadViewState (states [1]);
381 object IStateManager.SaveViewState ()
383 object[] states = new object[2];
384 states[0] = ViewState.SaveViewState();
385 states[1] = (items == null ? null : ((IStateManager)items).SaveViewState());
387 for (int i = 0; i < states.Length; i++) {
388 if (states [i] != null)
394 void IStateManager.TrackViewState ()
398 ViewState.TrackViewState();
401 ((IStateManager)items).TrackViewState ();
404 bool IStateManager.IsTrackingViewState
406 get { return marked; }
409 internal void SetDirty ()
411 ViewState.SetDirty (true);
416 object ICloneable.Clone ()
418 MenuItem nod = new MenuItem ();
419 foreach (DictionaryEntry e in ViewState)
420 nod.ViewState [(string)e.Key] = e.Value;
422 foreach (ICloneable c in ChildItems)
423 nod.ChildItems.Add ((MenuItem)c.Clone ());
428 internal void Bind (IHierarchyData hierarchyData)
430 this.hierarchyData = hierarchyData;
432 DataPath = hierarchyData.Path;
433 dataItem = hierarchyData.Item;
435 MenuItemBinding bin = GetBinding ();
438 // Bind Enabled property
440 if (bin.EnabledField != "")
441 try { Enabled = Convert.ToBoolean (GetBoundPropertyValue (bin.EnabledField)); }
442 catch { Enabled = bin.Enabled; }
444 Enabled = bin.Enabled;
446 // Bind ImageUrl property
448 if (bin.ImageUrlField.Length > 0) {
449 ImageUrl = Convert.ToString (GetBoundPropertyValue (bin.ImageUrlField));
450 if (ImageUrl.Length == 0)
451 ImageUrl = bin.ImageUrl;
453 else if (bin.ImageUrl.Length > 0)
454 ImageUrl = bin.ImageUrl;
456 // Bind NavigateUrl property
458 if (bin.NavigateUrlField.Length > 0) {
459 NavigateUrl = Convert.ToString (GetBoundPropertyValue (bin.NavigateUrlField));
460 if (NavigateUrl.Length == 0)
461 NavigateUrl = bin.NavigateUrl;
463 else if (bin.NavigateUrl.Length > 0)
464 NavigateUrl = bin.NavigateUrl;
466 // Bind PopOutImageUrl property
468 if (bin.PopOutImageUrlField.Length > 0) {
469 PopOutImageUrl = Convert.ToString (GetBoundPropertyValue (bin.PopOutImageUrlField));
470 if (PopOutImageUrl.Length == 0)
471 PopOutImageUrl = bin.PopOutImageUrl;
473 else if (bin.PopOutImageUrl.Length > 0)
474 PopOutImageUrl = bin.PopOutImageUrl;
476 // Bind Selectable property
478 if (bin.SelectableField != "")
479 try { Selectable = Convert.ToBoolean (GetBoundPropertyValue (bin.SelectableField)); }
480 catch { Selectable = bin.Selectable; }
482 Selectable = bin.Selectable;
484 // Bind SeparatorImageUrl property
486 if (bin.SeparatorImageUrlField.Length > 0) {
487 SeparatorImageUrl = Convert.ToString (GetBoundPropertyValue (bin.SeparatorImageUrlField));
488 if (SeparatorImageUrl.Length == 0)
489 SeparatorImageUrl = bin.SeparatorImageUrl;
491 else if (bin.SeparatorImageUrl.Length > 0)
492 SeparatorImageUrl = bin.SeparatorImageUrl;
494 // Bind Target property
496 if (bin.TargetField.Length > 0) {
497 Target = Convert.ToString (GetBoundPropertyValue (bin.TargetField));
498 if (Target.Length == 0)
501 else if (bin.Target.Length > 0)
504 // Bind ToolTip property
506 if (bin.ToolTipField.Length > 0) {
507 ToolTip = Convert.ToString (GetBoundPropertyValue (bin.ToolTipField));
508 if (ToolTip.Length == 0)
509 ToolTip = bin.ToolTip;
511 else if (bin.ToolTip.Length > 0)
512 ToolTip = bin.ToolTip;
514 // Bind Value property
516 if (bin.ValueField.Length > 0) {
517 value = Convert.ToString (GetBoundPropertyValue (bin.ValueField));
519 if (String.IsNullOrEmpty (value)) {
520 if (bin.Value.Length > 0)
522 else if (bin.Text.Length > 0)
525 value = String.Empty;
529 // Bind Text property
531 if (bin.TextField.Length > 0) {
532 text = Convert.ToString (GetBoundPropertyValue (bin.TextField));
533 if (bin.FormatString.Length > 0)
534 text = string.Format (bin.FormatString, text);
536 if (String.IsNullOrEmpty (text)) {
537 if (bin.Text.Length > 0)
539 else if (bin.Value.Length > 0)
548 Text = Value = GetDefaultBoundText ();
551 INavigateUIData navigateUIData = hierarchyData as INavigateUIData;
552 if (navigateUIData != null) {
553 ToolTip = navigateUIData.Description;
554 Text = navigateUIData.ToString ();
555 NavigateUrl = navigateUIData.NavigateUrl;
559 internal void SetDataItem (object item)
564 internal void SetDataPath (string path)
569 internal void SetDataBound (bool bound)
574 string GetDefaultBoundText ()
576 if (hierarchyData != null) return hierarchyData.ToString ();
577 else if (dataItem != null) return dataItem.ToString ();
578 else return string.Empty;
581 string GetDataItemType ()
583 if (hierarchyData != null) return hierarchyData.Type;
584 else if (dataItem != null) return dataItem.GetType().ToString ();
585 else return string.Empty;
588 MenuItemBinding GetBinding ()
590 if (menu == null) return null;
591 if (gotBinding) return binding;
592 binding = menu.FindBindingForItem (GetDataItemType (), Depth);
597 object GetBoundPropertyValue (string name)
599 if (boundProperties == null) {
600 if (hierarchyData != null)
601 boundProperties = TypeDescriptor.GetProperties (hierarchyData);
603 boundProperties = TypeDescriptor.GetProperties (dataItem);
606 PropertyDescriptor prop = boundProperties.Find (name, true);
608 throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
610 if (hierarchyData != null)
611 return prop.GetValue (hierarchyData);
613 return prop.GetValue (dataItem);