項目要求採用自己的模板驅動和UI結構致使不能使用任何ASP.NET內建控制項。
今天要給無限分類產生樹形結構,我參考了網上的一個演算法 據說是PHPCMS用的產生樹類。的確很帥,沒有太多時間直接照搬改成C#版。
/// <summary> /// 通用的樹型類,可以產生任何樹型結構 /// </summary> public class CateTreeView { IList<CategoryInfo> lsCate = new List<CategoryInfo>(); //初始化數組 string[] icons = new string[] { "│", "├", "└" }; //修飾符號 string htmlret = ""; string nbsp = " "; public CateTreeView(IList<CategoryInfo> ls) { lsCate = ls; htmlret = ""; } public CategoryInfo getOne(int id) { foreach (CategoryInfo m in lsCate) { if (m.cateid == id) { return m; } } return null; } /// <summary> /// 得到父級數組 /// </summary> /// <param name="myid"></param> /// <returns></returns> public IList<CategoryInfo> get_parent(int myid) { IList<CategoryInfo> lsnew = new List<CategoryInfo>(); CategoryInfo m = getOne(myid); if (m == null) return lsnew; int pid = m.parentid; if (pid == 0) return lsnew; pid = getOne(pid).parentid; foreach (CategoryInfo mcate in lsCate) { if (mcate.parentid == pid) { lsnew.Add(mcate); } } return lsnew; } /// <summary> /// 得到子級分類 /// </summary> /// <param name="myid"></param> /// <returns></returns> public IList<CategoryInfo> get_child(int myid) { IList<CategoryInfo> lsnew = new List<CategoryInfo>(); foreach (CategoryInfo mcate in lsCate) { if (mcate.parentid == myid) { lsnew.Add(mcate); } } return lsnew; } /// <summary> /// 得到樹型結構 /// </summary> /// <param name="myid">表示獲得這個ID下的所有子級</param> /// <param name="str">產生樹型結構的基本代碼,例如: option value=$id $selected $spacer$name option </param> /// <param name="sid">被選中的ID,比如在做樹型下拉框的時候需要用到</param> /// <param name="adds"></param> /// <param name="str_group"></param> /// <returns></returns> public string get_tree(int myid, string str, int sid, string adds, string str_group) { int number = 1; IList<CategoryInfo> child = get_child(myid); if (child.Count > 0) { int total = child.Count; foreach (CategoryInfo m in child) { string j = "", k = ""; if (number == total) { j += icons[2]; } else { j += icons[1]; k = adds != "" ? icons[0] : ""; } string spacer = adds != "" ? adds + j : ""; string selected = m.cateid == sid ? "selected" : ""; string tempstr = ""; if (m.parentid == 0 && str_group != "") //? "\$nstr = \"$str_group\";" : "\$nstr = \"$str\";"; { tempstr = str_group; } else { tempstr = str; } tempstr = tempstr.Replace("$id", m.cateid.ToString()); tempstr = tempstr.Replace("$parentid", m.parentid.ToString()); tempstr = tempstr.Replace("$select", selected); tempstr = tempstr.Replace("$spacer", spacer); tempstr = tempstr.Replace("$name", m.catename); tempstr = tempstr.Replace("$modelid", m.modelid.ToString()); htmlret += tempstr; string bspstr = nbsp; get_tree(m.cateid, str, sid, adds + k + bspstr, str_group); number++; //$this->ret .= $nstr; //$nbsp = $this->nbsp; //$this->get_tree($id, $str, $sid, $adds.$k.$nbsp,$str_group); //$number++; } } return htmlret; //return $this->ret; } /// <summary> /// 同上一類方法,jquery treeview 風格,可伸縮樣式(需要treeview外掛程式支援) /// </summary> /// <param name="myid">表示獲得這個ID下的所有子級</param> /// <param name="effected_id">需要產生treeview目錄數的id</param> /// <param name="str">末級樣式</param> /// <param name="str2">目錄層級樣式</param> /// <param name="showlevel">直接顯示層級數,其餘為非同步顯示,0為全部限制</param> /// <param name="style">目錄樣式 預設 filetree 可增加其他樣式如'filetree treeview-famfamfam</param> /// <param name="currentlevel">計算當前層級,遞迴使用 適用改函數時不需要用該參數</param> /// <param name="recursion">遞迴使用 外部調用時為FALSE</param> /// <returns>HTML</returns> public string get_treeview(int myid, string effected_id, string str, string str2, int showlevel, string style, int currentlevel, bool recursion) { IList<CategoryInfo> child = get_child(myid); string effected = "id=\"" + effected_id + "\""; string placeholder = "<ul><li><span class='placeholder'></span></li></ul>"; if (!recursion) htmlret += "<ul " + effected + " class=\"" + style + "\">"; foreach (CategoryInfo m in child) { IList<CategoryInfo> child2 = get_child(m.cateid); string folder = ""; //@extract($a); if (showlevel > 0 && showlevel == currentlevel && (child2.Count > 0)) folder = "hasChildren"; //如設定顯示層級模式@2011.07.01 string floder_status = ((folder != "") ? " class=\"" + folder + "\"" : ""); htmlret += recursion ? "<ul><li " + floder_status + " id=\"" + m.cateid + "\">" : "<li " + floder_status + " id=\"" + m.cateid + "\">"; recursion = false; if (child2.Count > 0) { string nstr = str2; //eval("\$nstr = \"$str2\";"); string tempstr = str2; tempstr = tempstr.Replace("$id", m.cateid.ToString()); tempstr = tempstr.Replace("$parentid", m.parentid.ToString()); //tempstr = tempstr.Replace("$select", selected); //tempstr = tempstr.Replace("$spacer", spacer); tempstr = tempstr.Replace("$name", m.catename); tempstr = tempstr.Replace("$modelid", m.modelid.ToString()); htmlret += tempstr; if (showlevel == 0 || (showlevel > 0 && showlevel > currentlevel)) { get_treeview(m.cateid, effected_id, str, str2, showlevel, style, currentlevel + 1, true); } else if (showlevel > 0 && showlevel == currentlevel) { htmlret += placeholder; } } else { string nstr = str; string tempstr = str; tempstr = tempstr.Replace("$id", m.cateid.ToString()); tempstr = tempstr.Replace("$parentid", m.parentid.ToString()); //tempstr = tempstr.Replace("$select", selected); //tempstr = tempstr.Replace("$spacer", spacer); tempstr = tempstr.Replace("$name", m.catename); tempstr = tempstr.Replace("$modelid", m.modelid.ToString()); htmlret += tempstr; //str += nstr; } htmlret += recursion ? "</li></ul>" : "</li>"; } if (!recursion)htmlret += "</ul>"; return htmlret; } }
沒有太高的複用性,用到的人自行改進把呵呵。別忘了改後再分享下。 其中CategoryInfo類是 分類實體類。
結合jquery treeview 外掛程式 做出的效果圖如下: