Основы ASP.NET 2.0

       

Программное управление TreeView


У TreeView есть множество событий. Событие SelectedNodeChanged запускается, когда пользователь выбирает узел:

protected void TreeLibrary_SelectedNodeChanged(object sender, EventArgs e) { Label1.Text = "Вы выбрали категорию " + TreeLibrary.SelectedNode.Text; }

Можно программно раскрывать и закрывать узлы:

TreeView1.ExpandAll(); TreeView1.CollapseAll();

Событие TreeNodePopulate позволяет динамически заполнять узлы, при этом можно экономить память, если заполнять узлы только по требованию после раскрытия родительского узла. Событие TreeNodePopulate вызывается, если действие (например, раскрытие) проведено с узлом, у которого SelectAction настроен на это действие.

В следующем примере заполним значения элемента управления TreeView из базы данных Northwind. Родительские узлы — категории продуктов, которые заполняются данными о продуктах тогда, когда узел необходимо раскрыть:

<asp:TreeView ID="TreeViewCatProd" runat="server" ImageSet="BulletedList3" OnTreeNodePopulate="TreeViewCatProd_TreeNodePopulate" ForeColor="DarkOliveGreen"> </asp:TreeView>

public partial class Products : System.Web.UI.Page { string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True";

protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { BindData(); } }

Вспомогательная функция устанавливает соединение с базой данных и возвращает SqlDataReader — самый быстрый способ чтения данных:


protected SqlDataReader CreateSqlDataReader(string SelectQuery, string ConnectionString) { SqlConnection Connection = new SqlConnection(ConnectionString); SqlCommand Command = new SqlCommand(SelectQuery, Connection); try { Command.CommandType = CommandType.Text; Command.Connection.Open(); SqlDataReader reader = Command.ExecuteReader(CommandBehavior.CloseConnection); return reader; } catch { Connection.Close(); return null; } }

При работе с базами данных важно перехватывать исключения:

protected void BindData() { TreeNode parentNode = null; SqlDataReader reader = CreateSqlDataReader("Select CategoryID,CategoryName from Categories", connectionString); if (reader!=null) { while (reader.Read()) { parentNode = new TreeNode(reader["CategoryName"].ToString(), reader["CategoryID"].ToString()); parentNode.Collapse(); parentNode.PopulateOnDemand = true; parentNode.SelectAction = TreeNodeSelectAction.Expand; TreeViewCatProd.Nodes.Add(parentNode); } reader.Close(); } }

Конструктор TreeNode может вызываться без параметров, но он перегружен. Вариант, который здесь используется, позволяет задать текст узла и значение Value (заполняется значением CategoryID), которое необходимо, чтобы найти в базе продукты этой категории.

При раскрытии узла с категорией будет вызываться обработчик:

protected void TreeViewCatProd_TreeNodePopulate(object sender, TreeNodeEventArgs e) { TreeNode node = e.Node; if (node.PopulateOnDemand) { string command = string.Format("Select ProductID, ProductName from Products where CategoryID={0}", node.Value); SqlDataReader reader = CreateSqlDataReader(command, connectionString); node.ChildNodes.Clear(); if (reader != null) { while (reader.Read()) { TreeNode childNode = new TreeNode(reader["ProductName"].ToString()); childNode.SelectAction = TreeNodeSelectAction.None; node.ChildNodes.Add(childNode); } node.Expand(); reader.Close(); } } }



TreeView позволяет не только показывать информацию, но ставить флажки рядом с узлами. Это полезно, если в нем содержится информация о товарах и пользователь может выбрать некоторые из них. Свойство ShowCheckBoxes допускает 5 значений: None, Root, Parent, Leaf, All:

ShowCheckBoxes="Leaf"

При этом рядом с узлами-листьями появляются флажки. Значение флажков можно прочитать программно:

<asp:XmlDataSource ID="XmlDataSource3" runat="server" DataFile="~/menu.xml"></asp:XmlDataSource> <asp:TreeView ID="TreeMenu" runat="server" DataSourceID="XmlDataSource3" BackColor="#FFFBD6" Font-Names="Verdana" Font-Size="0.8em" ForeColor="#990000" Height="78px" Width="415px" ShowCheckBoxes="Parent" OnTreeNodeCheckChanged="TreeMenu_TreeNodeCheckChanged" NodeWrap="True" PopulateNodesFromClient="False"> <DataBindings> <asp:TreeNodeBinding DataMember="name" ValueField="#InnerText" /> <asp:TreeNodeBinding DataMember="price" FormatString="{0} руб." TextField="#InnerText" ValueField="#InnerText" /> <asp:TreeNodeBinding DataMember="description" TextField="#InnerText" /> <asp:TreeNodeBinding DataMember="calories" FormatString="{0} калорий" TextField="#InnerText" /> <asp:TreeNodeBinding DataMember="food" TextField="name" /> <asp:TreeNodeBinding DataMember="pizza_menu" Text="Меню Пиццы" Value="Меню Пиццы" /> </DataBindings> </asp:TreeView> <asp:Label ID="Label1" runat="server" ></asp:Label>





Флажки стоят у родительских узлов, потому что именно там находятся названия блюд. В обработчике можно динамически показывать сумму текущего заказа:

protected void TreeMenu_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e) { decimal sumPrices=0.0M; if (TreeMenu.CheckedNodes.Count > 0) { Label1.Text = ""; foreach (TreeNode node in TreeMenu.CheckedNodes) { sumPrices += decimal.Parse(node.ChildNodes[0].Value); } Label1.Text = sumPrices.ToString() +"<br>"; } }

Цена записана в первом дочернем поле с индексом 0. При этом обращаться к свойству Text было бы неправильно, потому что там находится отформатированный текст, например, "306 руб.", который нельзя преобразовать в число.


Содержание раздела