之前学过委托和事件,这次看张波老师的电子商城第24讲,演示了通过在用户控件中自定义事件。
流程如下:(详细注释在代码中)
第一步当然是在aspx页面中拖入一个treeview控件了 :)
在C#文件中初始化treeview控件,并定义它的事件。
![]()
using 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上。
![]()
using 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
![]()
using 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);
}
}
}