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 return ViewState ["Text"] == null ? String.Empty : (String) ViewState ["Text"];
224 ViewState ["Text"] = value;
230 public string ToolTip {
232 return ViewState ["ToolTip"] == null ? String.Empty : (String) ViewState ["ToolTip"];
235 ViewState ["ToolTip"] = value;
241 public string Value {
243 return ViewState ["Value"] == null ? String.Empty : (String) ViewState ["Value"];
246 ViewState ["Value"] = value;
252 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
253 public string SeparatorImageUrl {
255 return ViewState ["SeparatorImageUrl"] == null ? String.Empty : (String) ViewState ["SeparatorImageUrl"];
258 ViewState ["SeparatorImageUrl"] = value;
262 [BrowsableAttribute (true)]
263 [DefaultValueAttribute (true)]
264 public bool Selectable {
266 return ViewState ["Selectable"] == null ? true : (bool) ViewState ["Selectable"];
269 ViewState ["Selectable"] = value;
273 [BrowsableAttribute (true)]
274 [DefaultValueAttribute (true)]
275 public bool Enabled {
277 return ViewState ["Enabled"] == null ? true : (bool) ViewState ["Enabled"];
280 ViewState ["Enabled"] = value;
284 internal bool BranchEnabled {
285 get { return Enabled && (parent == null || parent.BranchEnabled); }
288 [DefaultValue (false)]
290 public bool Selected {
293 return menu.SelectedItem == this;
299 if (!value && menu.SelectedItem == this)
300 menu.SetSelectedItem (null);
302 menu.SetSelectedItem (this);
307 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
309 public MenuItem Parent {
310 get { return parent; }
313 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
315 public string ValuePath {
317 if (menu == null) return Value;
319 StringBuilder sb = new StringBuilder (Value);
320 MenuItem item = parent;
321 while (item != null) {
322 sb.Insert (0, menu.PathSeparator);
323 sb.Insert (0, item.Value);
326 return sb.ToString ();
331 get { return index; }
332 set { index = value; ResetPathData (); }
335 internal void SetParent (MenuItem item) {
340 internal string Path {
342 if (path != null) return path;
343 StringBuilder sb = new StringBuilder (index.ToString());
344 MenuItem item = parent;
345 while (item != null) {
347 sb.Insert (0, item.Index.ToString ());
350 path = sb.ToString ();
355 internal bool HasChildData {
356 get { return items != null; }
359 void IStateManager.LoadViewState (object savedState)
361 if (savedState == null)
364 object[] states = (object[]) savedState;
365 ViewState.LoadViewState (states [0]);
367 if (states [1] != null)
368 ((IStateManager)ChildItems).LoadViewState (states [1]);
371 object IStateManager.SaveViewState ()
373 object[] states = new object[2];
374 states[0] = ViewState.SaveViewState();
375 states[1] = (items == null ? null : ((IStateManager)items).SaveViewState());
377 for (int i = 0; i < states.Length; i++) {
378 if (states [i] != null)
384 void IStateManager.TrackViewState ()
388 ViewState.TrackViewState();
391 ((IStateManager)items).TrackViewState ();
394 bool IStateManager.IsTrackingViewState
396 get { return marked; }
399 internal void SetDirty ()
401 ViewState.SetDirty (true);
406 object ICloneable.Clone ()
408 MenuItem nod = new MenuItem ();
409 foreach (DictionaryEntry e in ViewState)
410 nod.ViewState [(string)e.Key] = e.Value;
412 foreach (ICloneable c in ChildItems)
413 nod.ChildItems.Add ((MenuItem)c.Clone ());
418 internal void Bind (IHierarchyData hierarchyData)
420 this.hierarchyData = hierarchyData;
422 DataPath = hierarchyData.Path;
423 dataItem = hierarchyData.Item;
425 MenuItemBinding bin = GetBinding ();
428 // Bind Enabled property
430 if (bin.EnabledField != "")
431 try { Enabled = Convert.ToBoolean (GetBoundPropertyValue (bin.EnabledField)); }
432 catch { Enabled = bin.Enabled; }
434 Enabled = bin.Enabled;
436 // Bind ImageUrl property
438 if (bin.ImageUrlField.Length > 0) {
439 ImageUrl = Convert.ToString (GetBoundPropertyValue (bin.ImageUrlField));
440 if (ImageUrl.Length == 0)
441 ImageUrl = bin.ImageUrl;
443 else if (bin.ImageUrl.Length > 0)
444 ImageUrl = bin.ImageUrl;
446 // Bind NavigateUrl property
448 if (bin.NavigateUrlField.Length > 0) {
449 NavigateUrl = Convert.ToString (GetBoundPropertyValue (bin.NavigateUrlField));
450 if (NavigateUrl.Length == 0)
451 NavigateUrl = bin.NavigateUrl;
453 else if (bin.NavigateUrl.Length > 0)
454 NavigateUrl = bin.NavigateUrl;
456 // Bind PopOutImageUrl property
458 if (bin.PopOutImageUrlField.Length > 0) {
459 PopOutImageUrl = Convert.ToString (GetBoundPropertyValue (bin.PopOutImageUrlField));
460 if (PopOutImageUrl.Length == 0)
461 PopOutImageUrl = bin.PopOutImageUrl;
463 else if (bin.PopOutImageUrl.Length > 0)
464 PopOutImageUrl = bin.PopOutImageUrl;
466 // Bind Selectable property
468 if (bin.SelectableField != "")
469 try { Selectable = Convert.ToBoolean (GetBoundPropertyValue (bin.SelectableField)); }
470 catch { Selectable = bin.Selectable; }
472 Selectable = bin.Selectable;
474 // Bind SeparatorImageUrl property
476 if (bin.SeparatorImageUrlField.Length > 0) {
477 SeparatorImageUrl = Convert.ToString (GetBoundPropertyValue (bin.SeparatorImageUrlField));
478 if (SeparatorImageUrl.Length == 0)
479 SeparatorImageUrl = bin.SeparatorImageUrl;
481 else if (bin.SeparatorImageUrl.Length > 0)
482 SeparatorImageUrl = bin.SeparatorImageUrl;
484 // Bind Target property
\r
486 if (bin.TargetField.Length > 0) {
487 Target = Convert.ToString (GetBoundPropertyValue (bin.TargetField));
488 if (Target.Length == 0)
491 else if (bin.Target.Length > 0)
492 Target = bin.Target;
\r
494 // Bind ToolTip property
496 if (bin.ToolTipField.Length > 0) {
497 ToolTip = Convert.ToString (GetBoundPropertyValue (bin.ToolTipField));
498 if (ToolTip.Length == 0)
499 ToolTip = bin.ToolTip;
501 else if (bin.ToolTip.Length > 0)
502 ToolTip = bin.ToolTip;
504 // Bind Value property
506 if (bin.ValueField.Length > 0) {
507 Value = Convert.ToString (GetBoundPropertyValue (bin.ValueField));
508 if (Value.Length == 0)
510 if (Value.Length == 0)
513 else if (bin.Value.Length > 0)
515 else if (bin.Text.Length > 0)
518 Value = GetDefaultBoundText ();
520 // Bind Text property
522 if (bin.TextField.Length > 0) {
523 Text = Convert.ToString (GetBoundPropertyValue (bin.TextField));
524 if (bin.FormatString.Length > 0)
525 Text = string.Format (bin.FormatString, Text);
526 if (Text.Length == 0)
528 if (Text.Length == 0)
531 else if (bin.Text.Length > 0)
533 else if (bin.Value.Length > 0)
536 Text = GetDefaultBoundText ();
540 Text = Value = GetDefaultBoundText ();
543 INavigateUIData navigateUIData = hierarchyData as INavigateUIData;
544 if (navigateUIData != null) {
545 Text = navigateUIData.ToString ();
546 NavigateUrl = navigateUIData.NavigateUrl;
550 internal void SetDataItem (object item)
555 internal void SetDataPath (string path)
560 internal void SetDataBound (bool bound)
565 string GetDefaultBoundText ()
567 if (hierarchyData != null) return hierarchyData.ToString ();
568 else if (dataItem != null) return dataItem.ToString ();
569 else return string.Empty;
572 string GetDataItemType ()
574 if (hierarchyData != null) return hierarchyData.Type;
575 else if (dataItem != null) return dataItem.GetType().ToString ();
576 else return string.Empty;
579 MenuItemBinding GetBinding ()
581 if (menu == null) return null;
582 if (gotBinding) return binding;
583 binding = menu.FindBindingForItem (GetDataItemType (), Depth);
588 object GetBoundPropertyValue (string name)
590 if (boundProperties == null) {
591 if (hierarchyData != null)
592 boundProperties = TypeDescriptor.GetProperties (hierarchyData);
594 boundProperties = TypeDescriptor.GetProperties (dataItem);
597 PropertyDescriptor prop = boundProperties.Find (name, true);
599 throw new InvalidOperationException ("Property '" + name + "' not found in data bound item");
601 if (hierarchyData != null)
602 return prop.GetValue (hierarchyData);
604 return prop.GetValue (dataItem);