1.目标:当展开一个节点的时候,才加载此节点的子节点的子节点
如下图:第一次页面加载的时候,加载0级和1级,当点“河北省”节点的时,加载河北省的第2级(所有河北省的区级)
(其中:省级代表0级,市级代表1级,区级代表2级)
北京市
|
----北京市东城区
----北京市西城区
河北省
|
----河北省石家庄市
|
-------河北省石家庄市长安区
-------河北省石家庄市桥东区
----河北省唐山市
|
------河北省唐山市路南区
------河北省唐山市路北区
2.代码思路:
1.得到所有省的数据集(ds_Province) --->遍历ds_Province,将各个省与节点绑定 再加到根节点
--->遍历ds_Province的时候,将省的Id作为市的ParentId得到ds_City--->同理遍历ds_city 将市节点加到省节点
2.当点击省级节点(heibei)的时候,希望将此省的区级全部加到相应的市级,所以遍历此节点(heibei)的子节点集合
foreach (TreeNode subNode in e.Node.ChildNodes)--->在遍历的时候,将河北省的市节点的Id(subNode.value)作为区级的ParentId得到ds_County --->遍历ds_County 并将区节点加到市节点上
3.部分表结构:
DistictId DistrictName ParentDistrictId
130000 河北省 0
130100 河北省石家庄市 130000
130102 河北省石家庄市长安区 130100
130103 河北省石家庄市桥东区 130100
130104 河北省石家庄市桥西区 130100
4.代码:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//页面第一次加载的时候,加载第0级和第1级节点
if (!IsPostBack)
{
AddNode(0);
}
}
#region 页面加载时,加载第0级和第1级节点
private void AddNode(int parentDistrictId)
{
//通过传进来的参数,得到所有省的数据集
string strSQL = "SELECT * FROM [District] WHERE [ParentDistrictId]=@ParentDistrictId";
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@ParentDistrictId",parentDistrictId)
};
DataSet ds = GetDataSet(strSQL, paras);
//循环遍历,加载所有0级节点和1级节点
foreach (DataRow row in ds.Tables[0].Rows)
{
TreeNode node = new TreeNode();
node.Text = row["DistrictName"].ToString();
node.Value = row["DistrictId"].ToString();
TreeView1.Nodes.Add(node);
TreeView1.ExpandDepth = 0;
//加载1级节点
AddChildNodes(node);
}
}
#endregion
#region 增加子节点
public void AddChildNodes(TreeNode node)
{
string strSQL = "SELECT * FROM [District] WHERE [ParentDistrictId]=@ParentDistrictId";
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@ParentDistrictId",node.Value)
};
DataSet ds = GetDataSet(strSQL, paras);
foreach (DataRow row in ds.Tables[0].Rows)
{
TreeNode childNode = new TreeNode();
childNode.Text = row["DistrictName"].ToString();
childNode.Value = row["DistrictId"].ToString();
node.ChildNodes.Add(childNode);
//AddChildNodes(childNode);
}
}
#endregion
#region 通过sql语句,得到数据集
public static DataSet GetDataSet(string strSQL, params SqlParameter[] values)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["DistrictDBConnectionString1"].ConnectionString;
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 60;
cmd.CommandText = strSQL;
cmd.Parameters.AddRange(values);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds, 0, 5, "District");
return ds;
}
#endregion
#region 当点击第0级节点的时候,加载第1级的所有子节点
protected void TreeView1_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
{
foreach (TreeNode subNode in e.Node.ChildNodes)
{
subNode.ChildNodes.Clear();
}
foreach (TreeNode subNode in e.Node.ChildNodes)
{
AddChildNodes(subNode);
}
}
#endregion
}
5.需要改进的地方 及遇到的问题:
1.最理想的情况是:加载页面的时候,只加载省节点,点击省节点的时候只加载市节点
可是如果像那样设计的话,最开始加载页面的时候,加载的省节点没有加号,也就是说,无法通过点击省节点获得市节点了,可能TreeView这个控件就是这样设计的,只有节点内有内容才出现加号,否则就什么都不显示
现在的情况是:第一次加载的时候,显示第0级和第1级树,点第0级节点的时候,将此节点下的2级节点全部加上
2.感觉增加根节点的方法 和增加子节点的方法有冗余,我想如果上面的问题能解决的话,冗余估计就能很好的解决了
3.为什么这段代码,第一次加载很慢
4.不知道下面的2个遍历,哪个遍历的性能好一些
1.
foreach (TreeNode subNode in e.Node.ChildNodes)
{
subNode.ChildNodes.Clear();
}
foreach (TreeNode subNode in e.Node.ChildNodes)
{
AddChildNodes(subNode);
}
2.
foreach (TreeNode subNode in e.Node.ChildNodes)
{
subNode.ChildNodes.Clear();
AddChildNodes(subNode);
}