之前学过委托和事件,这次看张波老师的电子商城第24讲,演示了通过在用户控件中自定义事件。
流程如下:(详细注释在代码中)
第一步当然是在aspx页面中拖入一个treeview控件了 :)
在C#文件中初始化treeview控件,并定义它的事件。
UCCategoryTree.ascx.csusing System; public partial class Admin_UserControls_UCCategoryTree : System.Web.UI.UserControl { //用泛型类型参数的委托方式来声明一个事件CategorySelected,泛型类型参数指定事件所生成的事件数据的类型 //详见:http://www.cnblogs.com/philzhou/archive/2011/03/01/1967728.html public event EventHandler<CategoryEventArgs> CategorySelected = null; protected override void OnLoad(EventArgs e) { base.OnLoad(e); if (!IsPostBack) { //使用TreeViewCategory类的BuildTree方法将数据绑定到TreeView CategoryTreeBuilder.BuildTree(TreeViewCategory); } } protected void Page_Load(object sender, EventArgs e) { } protected void TreeViewCategory_SelectedNodeChanged(object sender, EventArgs e) { //***_SelectedNodeChanged事件是treeview控件自带的 if (this.TreeViewCategory.SelectedNode != null) { //如果选择了一个节点,即发生了_SelectedNodeChanged事件, //查看自定义的CategorySelected事件是否为空,不为空则以当前treeview控件为object sender参数:this.TreeViewCategory //以选中节点的ID为EventArgs e参数:new CategoryEventArgs() { CategoryID = int.Parse(this.TreeViewCategory.SelectedValue) } //用以上2个参数去执行CategorySelected事件中的方法,CategorySelected事件中的方法是在aspx页面page_load时通过委托的方式+=进去的:this.UCCategoryTree1.CategorySelected += new EventHandler<CategoryEventArgs>(UCCategoryTree1_CategorySelected); if (this.CategorySelected != null) { this.CategorySelected(this.TreeViewCategory, new CategoryEventArgs() { CategoryID = int.Parse(this.TreeViewCategory.SelectedValue) }); } } } }
在aspx页面中拖入刚才写好的用户控件UCCategoryTree.ascx,如下图:
在aspx页面的C#代码中给用户控件的CategorySelected事件赋值(装入要执行的方法),用户点击节点触发_SelectedNodeChanged事件后,执行CategorySelected事件里装入的方法,并将参数传给方法,方法通过参数获取节点的ID和名称然后显示到label上。
Category-UCTreeview.aspx.csusing System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; public partial class Category_UCTreeview : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { //通过委托给用户控件UCCategoryTree1的CategorySelected事件赋值,这里的委托要和CategorySelected所使用的委托的签名一致 this.UCCategoryTree1.CategorySelected += new EventHandler<CategoryEventArgs>(UCCategoryTree1_CategorySelected); } } public void UCCategoryTree1_CategorySelected(object sender, CategoryEventArgs e) { //e就是之前的:new CategoryEventArgs() { CategoryID = int.Parse(this.TreeViewCategory.SelectedValue) }, //是用户控件事件_SelectedNodeChanged触发后,执行CategorySelected里装入的方法时,主动将e中的数据CategoryID以参数的形式传给方法UCCategoryTree1_CategorySelected的,故e.CategoryID是推送形式。 //而(sender as TreeView).SelectedNode.Text是得到sender参数后,读取它的.SelectedNode.Text值,所以是拉入形式。 this.Label1.Text = string.Format("推ID:{0},<br/>拉:Text:{1}", e.CategoryID, (sender as TreeView).SelectedNode.Text); } }
附上将数据绑定到treeview控件的类的代码CategoryTreeBuilder.cs
CategoryTreeBuilder.csusing System;
using System.Web.UI.WebControls;
/// <summary>
/// Summary description for TreeBuilder
/// </summary>
public class CategoryTreeBuilder
{
private static AdminDataSetTableAdapters.CategoriesTableAdapter adapter;
static CategoryTreeBuilder()
{
adapter = new AdminDataSetTableAdapters.CategoriesTableAdapter();
}
public static void BuildTree(TreeView tree)
{
tree.Nodes.Clear();
//GetDataTopNodes()取所有根节点
AdminDataSet.CategoriesDataTable topNodes = adapter.GetDataTopNodes();
//循环构造每个根节点的子节点 而每一个子节点还可能有子节点,用递归构造出一个(根节点-子节点-孙子节点)的树形结构
foreach (AdminDataSet.CategoriesRow row in topNodes)
{
TreeNode node = new TreeNode();
node.Value = row.CategoryID.ToString();
node.Text = row.CategoryName;
//node.NavigateUrl = "~/Admin/Category.aspx?id="+row.CategoryID;
BuildNode(node);
tree.Nodes.Add(node);
}
}
private static void BuildNode(TreeNode node)
{
//取当前node所有子节点
//把每个子节点添加到当前节点
//递归得出当前子节点的子节点,构造出它的子节点树,
int id=int.Parse(node.Value);
foreach (var row in adapter.GetDataByParentCategoryID(id))
{
TreeNode childnode = new TreeNode()
{
Text = row.CategoryName,
Value = row.CategoryID.ToString(),
//NavigateUrl="~/Admin/Category.aspx?id="+row.CategoryID
};
BuildNode(childnode);
node.ChildNodes.Add(childnode);
}
}
}