using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using DaveControls.HierarchicalControls.Data;
using System.Text;
namespace Samples
{
public partial class TreeView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// need to add the client id of the expand collapse states hidden field so that javascript can access it
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "expandCollapseHiddenFieldId", String.Format("var expandCollapseHiddenFieldId = '{0}';", ExpandCollapseStatesHiddenField.ClientID), true);
if (!IsPostBack)
{
DataBindList();
}
else
{
// re-databind the tree view to preserve the users expand/collapse changes
ReDataBindList();
}
}
/// <summary>
/// This method will re-data bind the tree view from the original datasource, but will keep the
/// item's expand and collapse states set by the user.
/// </summary>
private void ReDataBindList()
{
TreeViewTestData dataSource = TestDataSource;
string currentExpandCollapseStates = ExpandCollapseStatesHiddenField.Value;
int index = 0;
SetDataSourceExpandCollapseStates(dataSource, ref index, currentExpandCollapseStates);
TreeViewHierarchicalRepeater.DataSource = dataSource;
TreeViewHierarchicalRepeater.DataBind();
}
/// <summary>
/// This method recurses through the datasource and sets the "Expanded" property for each dataitem
/// according the the expand/collapse states string
/// </summary>
/// <param name="dataSource">The datasource to recurse through</param>
/// <param name="index">the current index of the state string representing the current tree node</param>
/// <param name="currentExpandCollapseStates">the string representing the expand/collapse states to set</param>
private void SetDataSourceExpandCollapseStates(TreeViewTestData dataSource, ref int index, string currentExpandCollapseStates)
{
for (int i = 0; i < dataSource.Count; i++)
{
TreeViewTestData item = (TreeViewTestData)dataSource[i];
if (index >= currentExpandCollapseStates.Length)
{
// the expand collapse states string is too short for the
// amount of items in the expand string
throw new Exception("The ExpandCollapseState string for the treeview is too short");
}
else
{
char c = currentExpandCollapseStates[index];
if (c == 'e')
{
item.Expanded = true;
}
else if (c == 'c')
{
item.Expanded = false;
}
}
index++;
if (item.HasChildren)
{
SetDataSourceExpandCollapseStates(item, ref index, currentExpandCollapseStates);
}
}
}
/// <summary>
/// This method will databind the tree view with the item's expand/collapse states from the original
/// datasource. Calling this method in post back will cause the display to loose the item's expand and
/// collapse states that have been changed by the user.
/// </summary>
private void DataBindList()
{
TreeViewHierarchicalRepeater.DataSource = TestDataSource;
TreeViewHierarchicalRepeater.DataBind();
// we need to load the tree view state hidden field with a string to represent the
// required expand/collapse state of all of the treeview items.
// By doing this, javascript will be able to access the states client side, and they
// can be persisted accross postbacks.
StringBuilder sb = new StringBuilder();
// recurse through the nodes
BuildExpandCollapseStates(TestDataSource, sb);
// set the hidden field with the expand/collapse states string
ExpandCollapseStatesHiddenField.Value = sb.ToString();
}
/// <summary>
/// This method recursively traverses the tree view to build a string with the nodes'
/// expand/collapse states
/// </summary>
/// <param name="dataSource"></param>
/// <param name="sb"></param>
private void BuildExpandCollapseStates(TreeViewTestData dataSource, StringBuilder sb)
{
IEnumerator dataEnum = dataSource.GetEnumerator();
while (dataEnum.MoveNext())
{
TreeViewTestData item = (TreeViewTestData)dataEnum.Current;
// add "e" if the item is expanded or "c" if it is collapsed
sb.Append(item.Expanded ? "e" : "c");
if (item.HasChildren)
{
BuildExpandCollapseStates(item, sb);
}
}
}
/// <summary>
/// This method is called when the user clicks on an item in the control. It locates the item from the
/// data source and displays its description next to the control.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void TreeViewHierarchicalRepeater_ItemCommand(object sender, DaveControls.HierarchicalControls.HierarchicalRepeaterCommandEventArgs e)
{
if (e.CommandName == "ClickItem")
{
string path = e.CommandArgument.ToString();
HierarchyDataItemBase selectedItem = TestDataSource.GetItem(path);
if (selectedItem != null)
{
TreeViewTestData item = (TreeViewTestData)selectedItem;
ItemTextLiteral.Text = item.Text;
ItemDescriptionLiteral.Text = item.Description;
DescriptionPlaceholder.Visible = true;
NoDescriptionPlaceholder.Visible = false;
}
}
}
/// <summary>
/// This is the data source the HierarchicalRepeater control will be data bound to.
/// The HierarchicalRepeater control requires its datasource object to inherit HierarchyDataItemBase
/// </summary>
private TreeViewTestData _testDataSource;
private TreeViewTestData TestDataSource
{
get
{
if (_testDataSource == null)
{
_testDataSource = new TreeViewTestData("rootItem", "this is the root and will be ignored", true);
TreeViewTestData item1 = new TreeViewTestData("Pie", "New flavours available", false);
item1.Add(new TreeViewTestData("Steak and ale", "Beef steak stewed in Westcountry Ale", false));
item1.Add(new TreeViewTestData("Chicken and mushroom", "A traditional favourite pie", false));
_testDataSource.Add(item1);
_testDataSource.Add(new TreeViewTestData("Cake", "Chocolate sponge", false));
TreeViewTestData item3 = new TreeViewTestData("Fruit", "A healthy option", true);
TreeViewTestData item3a = new TreeViewTestData("Apples", "Different varieties available", false);
TreeViewTestData item3b = new TreeViewTestData("Pears", "A juicy snack", true);
TreeViewTestData item3c = new TreeViewTestData("Oranges", "High in Vitamin C", false);
item3.Add(item3a);
item3.Add(item3b);
item3.Add(item3c);
TreeViewTestData item3a1 = new TreeViewTestData("Granny Smith", "A tangy green apple", false);
TreeViewTestData item3a2 = new TreeViewTestData("Goldern Delicious", "A crisp red apple", true);
item3a.Add(item3a1);
item3a.Add(item3a2);
_testDataSource.Add(item3);
TreeViewTestData item4 = new TreeViewTestData("Crisps", "Called 'chips' most places in the world, but 'crisps' in the UK", false);
item4.Add(new TreeViewTestData("Ready salted", "Perfect for a mid-morning snack", false));
item4.Add(new TreeViewTestData("Salt and Vinegar", "For those who like a little more tang", false));
_testDataSource.Add(item4);
}
return _testDataSource;
}
}
/// <summary>
/// This class represents the datasource and dataitems the HierarchicalRepeater control will bind to.
/// It inherits HierarchyDataItemBase as required, and the additional properties are specific to this
/// sample and can be data bound to in the ItemTemplate, ChildrenHeaderTemplate and FooterHeaderTemplate
/// of the control.
///
/// The property "Expanded" has been added to represent the whether the tree node should be expanded or
/// collapsed.
/// </summary>
private class TreeViewTestData : HierarchyDataItemBase
{
private string _description;
public string Description
{
get { return _description; }
set { _description = value; }
}
private string _text;
public string Text
{
get { return _text; }
set { _text = value; }
}
private bool _expanded;
public bool Expanded
{
get { return _expanded; }
set { _expanded = value; }
}
public TreeViewTestData(string text, string description, bool expanded)
{
_text = text;
_description = description;
_expanded = expanded;
}
}
}
}