分享自己写的动态绑定TreeView,非递归(做查询BOM的可以了解一下)

PitTroll 2010-10-24 10:52:14

/// <summary>
/// 绑定BOM
/// </summary>
/// <param name="tvwBOM">绑定BOM的TreeView控件</param>
/// <param name="chpPTNB">成品料号</param>
public void BindBOM(TreeView tvwBOM, string chpPTNB)
{
try
{
tvwBOM.Nodes.Clear();//清除所有的节点

List<TreeNode> allBOMItems = new List<TreeNode>();//存放所有的BOM节点
TreeNode root = new TreeNode(chpPTNB, chpPTNB);//创建根节点
root.Expanded = true;//默认展开

tvwBOM.Nodes.Add(root);//添加根节点
allBOMItems.Add(root);//保存根节点

using (SqlConnection con = new SqlConnection(Common.connectionString))
{
for (int i = 0; i < allBOMItems.Count; i++)//添加所有的BOM节点
{
string parentPTNB = allBOMItems[i].Value;//获取父节点的值
string sql = "select childPTNB,childPTNB+'*'+convert(nvarchar(20),qtty)+useUnit as text from bom where parentPTNB=@parentPTNB";//查询子节点料号信息
SqlDataReader sdr = GetDataReader(sql, con, new SqlParameter("@parentPTNB", parentPTNB));
if (sdr != null)
{
while (sdr.Read())
{
TreeNode tn = new TreeNode(sdr["text"].ToString(), sdr["childPTNB"].ToString());//创建子节点
tn.Expanded = true;//默认展开

allBOMItems[i].ChildNodes.Add(tn);//添加子节点
allBOMItems.Add(tn);//保存子节点
}
sdr.Close();
}
}
}
}
catch
{
//TODO
}
}

#region 代码生成器生成的

/// <summary>
/// 执行查询语句,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="strSQL">查询语句</param>
/// <returns>SqlDataReader</returns>
public SqlDataReader GetDataReader(string SQLString, SqlConnection conn,params SqlParameter[] cmdParms)
{
SqlCommand cmd = new SqlCommand();
try
{
PrepareCommand(cmd, conn, SQLString, cmdParms);
SqlDataReader myReader = cmd.ExecuteReader();
cmd.Parameters.Clear();
return myReader;
}
catch (Exception ex)
{
WriteError(ex.Message);
return null;
}
}

private void PrepareCommand(SqlCommand cmd, SqlConnection conn, string cmdText, SqlParameter[] cmdParms)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
if (cmdParms != null)
{
foreach (SqlParameter parameter in cmdParms)
{
if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
(parameter.Value == null))
{
parameter.Value = DBNull.Value;
}
cmd.Parameters.Add(parameter);
}
}
}

#endregion


代码仅供参考。数据库表:BOM,字段:parentPTNB是父阶厂内料号,childPTNB是子阶厂内料号,qtty是一单位父阶料号的子阶数量,useUnit是子阶料号的使用单位。
采用的方法姑且叫伪迭代吧。我是觉得用递归不太好,BOM深度不深感觉还没出来,但是像报纸上卖瓷器的:有108道工序如果用TreeView显示用递归的话,我估计够呛。
有用到动态绑定TreeView的、不想用递归的、不会用递归的可以参考一下。
...全文
559 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
PitTroll 2010-10-24
  • 打赏
  • 举报
回复
俺倒是觉得递归这个东西能不用就不用。做任何东西必然要有牺牲,例如:牺牲时间换空间,牺牲空间换时间等。但是像递归这样以牺牲空间和时间换代码简洁,牺牲的东西太多了点。当然有时候递归也用着还是很方便的,例如客户要求用表格显示有层次关系的BOM的时候,递归就方便多了。这个做ERP的人肯定有这方面的经验。
wuyq11 2010-10-24
  • 打赏
  • 举报
回复
支 持
兔子-顾问 2010-10-24
  • 打赏
  • 举报
回复
mark.
支持分享。
GDick2010 2010-10-24
  • 打赏
  • 举报
回复
谢谢了!!!
PitTroll 2010-10-24
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 sp1234 的回复:]
另外TreeView深度如果超过3层,一次加载那么多节点有什么必要?
[/Quote]
客户在查询BOM的时候都TM要一次显示完全的,说白了就是脑残型。面对这样的客户我该怎么说呢。
PitTroll 2010-10-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 sp1234 的回复:]
引用楼主 pittroll 的回复:
但是像报纸上卖瓷器的:有108道工序如果用TreeView显示用递归的话,我估计够呛。


别只是估计呀,写一个测试出来!
[/Quote]
以前写斐波那契数列,用递归到40层左右就慢了很多。这个多层就没有试过,客户工艺路线做多10层左右。用递归感觉不出来。
  • 打赏
  • 举报
回复
其实所谓递归,也就是自动编译出使用堆栈的代码来,跟你使用自动增长的allBOMItems 是同一个道理,只不过是编译程序自动将当前正在处理的物料Item以及tn压入堆栈(因为是局部变量),而树本身不是方法内的变量所以不会在堆栈上压入。

递归代码代码中简洁得根本不用声明 allBOMItems。
  • 打赏
  • 举报
回复
另外TreeView深度如果超过3层,一次加载那么多节点有什么必要?
  • 打赏
  • 举报
回复
[Quote=引用楼主 pittroll 的回复:]
但是像报纸上卖瓷器的:有108道工序如果用TreeView显示用递归的话,我估计够呛。
[/Quote]

别只是估计呀,写一个测试出来!

110,502

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧