//
// System.Web.UI.WebControls.TreeNode.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, "ChildNodes")]
public class TreeNode: IStateManager, ICloneable
{
StateBag ViewState = new StateBag ();
TreeNodeCollection nodes;
bool marked;
TreeView tree;
TreeNode parent;
int index;
string path;
int depth = -1;
object dataItem;
IHierarchyData hierarchyData;
bool gotBinding;
TreeNodeBinding binding;
PropertyDescriptorCollection boundProperties;
bool populating;
bool hadChildrenBeforePopulating;
internal TreeNode (TreeView tree)
{
Tree = tree;
}
public TreeNode ()
{
}
public TreeNode (string text)
{
Text = text;
}
public TreeNode (string text, string value)
{
Text = text;
Value = value;
}
public TreeNode (string text, string value, string imageUrl)
{
Text = text;
Value = value;
ImageUrl = imageUrl;
}
public TreeNode (string text, string value, string imageUrl, string navigateUrl, string target)
{
Text = text;
Value = value;
ImageUrl = imageUrl;
NavigateUrl = navigateUrl;
Target = target;
}
[MonoTODO ("Not implemented")]
protected TreeNode (TreeView owner, bool isRoot)
{
throw new NotImplementedException ();
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[Browsable (false)]
public int Depth {
get {
if (depth != -1) return depth;
depth = 0;
TreeNode nod = parent;
while (nod != null) {
depth++;
nod = nod.parent;
}
return depth;
}
}
void ResetPathData ()
{
path = null;
depth = -1;
gotBinding = false;
if (nodes != null) {
foreach (TreeNode node in nodes)
node.ResetPathData ();
}
}
internal TreeView Tree {
get { return tree; }
set {
if (SelectedFlag) {
if (value != null)
value.SetSelectedNode (this, false);
if (tree != null)
tree.SetSelectedNode (null, false);
}
tree = value;
if (nodes != null)
nodes.SetTree (tree);
ResetPathData ();
if (PopulateOnDemand && !Populated && Expanded.HasValue && Expanded.Value)
Populate ();
}
}
[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 { 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; }
}
[DefaultValue (false)]
public bool Checked {
get {
object o = ViewState ["Checked"];
if (o != null) return (bool)o;
return false;
}
set {
ViewState ["Checked"] = value;
if (tree != null)
tree.NotifyCheckChanged (this);
}
}
[DefaultValue (null)]
[MergableProperty (false)]
[Browsable (false)]
[PersistenceMode (PersistenceMode.InnerDefaultProperty)]
public TreeNodeCollection ChildNodes {
get {
if (nodes == null) {
nodes = new TreeNodeCollection (this);
if (IsTrackingViewState)
((IStateManager)nodes).TrackViewState();
}
return nodes;
}
}
[DefaultValue (null)]
public bool? Expanded {
get {
object o = ViewState ["Expanded"];
return (bool?)o;
}
set {
bool? current = (bool?) ViewState ["Expanded"];
if (current == value)
return;
ViewState ["Expanded"] = value;
if (tree != null)
tree.NotifyExpandedChanged (this);
if (PopulateOnDemand && !Populated && value.HasValue && value.Value)
Populate ();
}
}
[Localizable (true)]
[DefaultValue ("")]
public string ImageToolTip {
get {
object o = ViewState ["ImageToolTip"];
if (o != null)
return (string)o;
return String.Empty;
}
set { ViewState ["ImageToolTip"] = value; }
}
[DefaultValue ("")]
[UrlProperty]
[Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
public string ImageUrl {
get {
object o = ViewState ["ImageUrl"];
if (o != null)
return (string)o;
return String.Empty;
}
set { ViewState ["ImageUrl"] = value; }
}
[DefaultValue ("")]
[UrlProperty]
[Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, typeof (System.Drawing.Design.UITypeEditor))]
public string NavigateUrl {
get {
object o = ViewState ["NavigateUrl"];
if (o != null)
return (string)o;
return String.Empty;
}
set { ViewState ["NavigateUrl"] = value; }
}
internal bool HadChildrenBeforePopulating {
get { return hadChildrenBeforePopulating; }
set {
if (populating)
return;
hadChildrenBeforePopulating = value;
}
}
[DefaultValue (false)]
public bool PopulateOnDemand {
get {
object o = ViewState ["PopulateOnDemand"];
if (o != null)
return (bool)o;
return false;
}
set {
ViewState ["PopulateOnDemand"] = value;
if (value && nodes != null && nodes.Count > 0)
HadChildrenBeforePopulating = true;
else
HadChildrenBeforePopulating = false;
}
}
[DefaultValue (TreeNodeSelectAction.Select)]
public TreeNodeSelectAction SelectAction {
get {
object o = ViewState ["SelectAction"];
if (o != null)
return (TreeNodeSelectAction)o;
return TreeNodeSelectAction.Select;
}
set { ViewState ["SelectAction"] = value; }
}
[DefaultValue (null)]
public bool? ShowCheckBox {
get {
object o = ViewState ["ShowCheckBox"];
return (bool?)o;
}
set { ViewState ["ShowCheckBox"] = value; }
}
internal bool ShowCheckBoxInternal {
get {
if (ShowCheckBox.HasValue)
return ShowCheckBox.Value;
else
return (Tree.ShowCheckBoxes == TreeNodeTypes.All) ||
((Tree.ShowCheckBoxes & TreeNodeTypes.Leaf) > 0 && IsLeafNode) ||
((Tree.ShowCheckBoxes & TreeNodeTypes.Parent) > 0 && IsParentNode && Parent != null) ||
((Tree.ShowCheckBoxes & TreeNodeTypes.Root) > 0 && Parent == null && ChildNodes.Count > 0);
}
}
[DefaultValue ("")]
public string Target {
get {
object o = ViewState ["Target"];
if(o != null)
return (string)o;
return String.Empty;
}
set { ViewState ["Target"] = value; }
}
[Localizable (true)]
[DefaultValue ("")]
[WebSysDescription ("The display text of the tree node.")]
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 {
object o = ViewState ["ToolTip"];
if(o != null)
return (string)o;
return String.Empty;
}
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 (false)]
public bool Selected {
get { return SelectedFlag; }
set {
SelectedFlag = value;
if (tree != null) {
if (!value && tree.SelectedNode == this)
tree.SetSelectedNode (null, false);
else if (value)
tree.SetSelectedNode (this, false);
}
}
}
internal virtual bool SelectedFlag {
get {
object o = ViewState ["Selected"];
if(o != null)
return (bool)o;
return false;
}
set { ViewState ["Selected"] = value; }
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[Browsable (false)]
public TreeNode Parent {
get { return parent; }
}
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[Browsable (false)]
public string ValuePath {
get {
if (tree == null) return Value;
StringBuilder sb = new StringBuilder (Value);
TreeNode node = parent;
while (node != null) {
sb.Insert (0, tree.PathSeparator);
sb.Insert (0, node.Value);
node = node.Parent;
}
return sb.ToString ();
}
}
internal int Index {
get { return index; }
set { index = value; ResetPathData (); }
}
internal void SetParent (TreeNode node)
{
parent = node;
ResetPathData ();
}
internal string Path {
get {
if (path != null)
return path;
StringBuilder sb = new StringBuilder (index.ToString());
TreeNode node = parent;
while (node != null) {
sb.Insert (0, '_');
sb.Insert (0, node.Index.ToString ());
node = node.Parent;
}
path = sb.ToString ();
return path;
}
}
internal bool Populated {
get {
object o = ViewState ["Populated"];
if (o != null)
return (bool) o;
return false;
}
set { ViewState ["Populated"] = value; }
}
internal bool HasChildData {
get { return nodes != null; }
}
internal void Populate ()
{
if (tree == null)
return;
populating = true;
tree.NotifyPopulateRequired (this);
populating = false;
Populated = true;
}
public void Collapse ()
{
Expanded = false;
}
public void CollapseAll ()
{
SetExpandedRec (false, -1);
}
public void Expand ()
{
Expanded = true;
}
internal void Expand (int depth)
{
SetExpandedRec (true, depth);
}
public void ExpandAll ()
{
SetExpandedRec (true, -1);
}
void SetExpandedRec (bool expanded, int depth)
{
Expanded = expanded;
if (depth == 0)
return;
foreach (TreeNode nod in ChildNodes)
nod.SetExpandedRec (expanded, depth - 1);
}
public void Select ()
{
Selected = true;
}
public void ToggleExpandState ()
{
#if TARGET_JVM //No support for Nullable<bool>.GetValueOrDefault() yet
bool? value = Expanded;
Expanded = value.HasValue ? !value.Value : true;
#else
Expanded = !Expanded.GetValueOrDefault(false);
#endif
}
void IStateManager.LoadViewState (object savedState)
{
LoadViewState (savedState);
}
protected virtual void LoadViewState (object savedState)
{
if (savedState == null)
return;
object[] states = (object[]) savedState;
ViewState.LoadViewState (states [0]);
if (tree != null && SelectedFlag)
tree.SetSelectedNode (this, true);
if (!PopulateOnDemand || Populated)
((IStateManager)ChildNodes).LoadViewState (states [1]);
}
object IStateManager.SaveViewState ()
{
return SaveViewState ();
}
protected virtual object SaveViewState ()
{
object[] states = new object[2];
states[0] = ViewState.SaveViewState();
states[1] = (nodes == null ? null : ((IStateManager)nodes).SaveViewState());
for (int i = 0; i < states.Length; i++) {
if (states [i] != null)
return states;
}
return null;
}
void IStateManager.TrackViewState ()
{
TrackViewState ();
}
protected void TrackViewState ()
{
if (marked) return;
marked = true;
ViewState.TrackViewState();
if (nodes != null)
((IStateManager)nodes).TrackViewState ();
}
bool IStateManager.IsTrackingViewState {
get { return IsTrackingViewState; }
}
protected bool IsTrackingViewState {
get { return marked; }
}
internal void SetDirty ()
{
ViewState.SetDirty (true);
if (nodes != null)
nodes.SetDirty ();
}
public virtual object Clone ()
{
TreeNode nod = tree != null ? tree.CreateNode () : new TreeNode ();
foreach (DictionaryEntry e in ViewState)
nod.ViewState [(string)e.Key] = ((StateItem)e.Value).Value;
foreach (TreeNode c in ChildNodes)
nod.ChildNodes.Add ((TreeNode)c.Clone ());
return nod;
}
object ICloneable.Clone ()
{
return Clone ();
}
internal void Bind (IHierarchyData hierarchyData)
{
this.hierarchyData = hierarchyData;
DataBound = true;
DataPath = hierarchyData.Path;
dataItem = hierarchyData.Item;
TreeNodeBinding bin = GetBinding ();
if (bin != null) {
// Bind ImageToolTip property
if (bin.ImageToolTipField.Length > 0) {
ImageToolTip = Convert.ToString (GetBoundPropertyValue (bin.ImageToolTipField));
if (ImageToolTip.Length == 0)
ImageToolTip = bin.ImageToolTip;
} else if (bin.ImageToolTip.Length > 0)
ImageToolTip = bin.ImageToolTip;
// 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 PopulateOnDemand property
if (bin.HasPropertyValue ("PopulateOnDemand"))
PopulateOnDemand = bin.PopulateOnDemand;
// Bind SelectAction property
if (bin.HasPropertyValue ("SelectAction"))
SelectAction = bin.SelectAction;
// Bind ShowCheckBox property
if (bin.HasPropertyValue ("ShowCheckBox"))
ShowCheckBox = bin.ShowCheckBox;
// 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 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;
}
if (!String.IsNullOrEmpty (text))
Text = text;
// 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;
}
if (!String.IsNullOrEmpty (value))
Value = value;
} else {
Text = Value = GetDefaultBoundText ();
}
INavigateUIData navigateUIData = hierarchyData as INavigateUIData;
if (navigateUIData != null) {
SelectAction = TreeNodeSelectAction.None;
Text = navigateUIData.ToString ();
NavigateUrl = navigateUIData.NavigateUrl;
ToolTip = navigateUIData.Description;
}
}
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;
}
internal bool IsParentNode {
get { return ChildNodes.Count > 0 || (PopulateOnDemand && !Populated); }
}
internal bool IsLeafNode {
get { return !IsParentNode; }
}
internal bool IsRootNode {
get { return Depth == 0; }
}
TreeNodeBinding GetBinding ()
{
if (tree == null)
return null;
if (gotBinding)
return binding;
binding = tree.FindBindingForNode (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);
}
internal void BeginRenderText (HtmlTextWriter writer)
{
RenderPreText (writer);
}
internal void EndRenderText (HtmlTextWriter writer)
{
RenderPostText (writer);
}
protected virtual void RenderPreText (HtmlTextWriter writer)
{
}
protected virtual void RenderPostText (HtmlTextWriter writer)
{
}
}
}
#endif
|