1. 程式人生 > >動手做ASP.NET 2.0伺服器端控制元件——AutoCheckTreeView(一)功能討論

動手做ASP.NET 2.0伺服器端控制元件——AutoCheckTreeView(一)功能討論

感謝譚振林先生所著《道不遠人——深入解析ASP.NET 2.0控制元件開發》

 ASP.NET現在使用的朋友是越來越多了,而其中一些很“方便”的控制元件事實上在實際使用過程中卻不是那麼方便。還好,我們有辦法改善它們,或者是繼承現有控制元件後擴充套件,或者是繼承Control或者CompositeControl重寫一個新的控制元件。這些方法請參見《道不遠人》,小凡用在此書中學到的知識重寫了很多控制元件,今天為大家介紹——AutoCheckTreeView

顧名思義,AutoCheckTreeView是由TreeView繼承而來。相信大家都用過TreeView,好處自然不用多說,那我們來回憶批鬥一下這個控制元件的不足之處吧。

一,TreeView控制元件的節點勾選框不支援父子節點自動勾選,例如下面這個樹形結構,並且節點存在CheckBox

--父1

   --子1

      --孫1

   --子2

      --孫2

      --孫3

如果勾選了“子1”節點,“父1”和“孫1”節點是不能自動勾選的。同樣的,如果一個節點取消勾選,該節點的子節點也不能全部取消勾選。誠然,有些時候是不需要這樣的功能的,可是,如果需要呢?怎麼辦?小凡的開發過程中,大概這種需求是55分成。

二,TreeView不支援DataSource的繫結功能

TreeView的DataSource是由父控制元件繼承而來,但是,這個屬性在TreeView中毫無用處,浪費了一大資源。而且顯然,微軟也考慮的並不足夠。相信大家在專案開發過程中,很多時候都使用樹形結構表來記錄樹形資料,最簡單的情況[選單主鍵,父選單主鍵,選單名稱],這樣就定義成功了一個選單樹形結構。好吧,當做維護介面時,當然就會選擇TreeView來進行維護比較方便。然而,如何把資料庫資料對映到介面上?現在的做法,唯有使用遞迴或者其它方法來一層一層架構。如果只有一個介面,那還不錯,如果又有其它樹形結構資料呢?繼續做一次重複程式碼?不!我們做一個控制元件支援這樣的功能,所有的問題都解決了!

在C#中,樹形結構一般會出現下面的兩種情況:

1)DataTable記錄樹形結構

  1. DataSet ds = new DataSet();
  2. DataTable dt = new DataTable("table");
  3. ds.Tables.Add(dt);
  4. dt.Columns.Add("name");
  5. dt.Columns.Add("value");
  6. dt.Columns.Add("id");
  7. dt.Columns.Add("pid");
  8. dt.Rows.Add("子1""sdf", 3, 1);
  9. dt.Rows.Add("父1""sdf", 1, 0);
  10. dt.Rows.Add("子2"
    "sdf", 5, 2);
  11. dt.Rows.Add("孫1""sdf", 4, 3);
  12. dt.Rows.Add("父2""sdf", 2, 0);

2)使用擴充套件自IEnumerable的資料結構,並且物件的Property記錄來對應

首先定義一個Class結構

  1. [Serializable]
  2. class A
  3. {
  4. privatestring name;
  5. publicstring Name
  6.     {
  7. get { return name; }
  8. set { name = value; }
  9.     }
  10. privatestring value;
  11. publicstring Value
  12.     {
  13. get { returnthis.value; }
  14. set { this.value = value; }
  15.     }
  16. privateint id;
  17. publicint Id
  18.     {
  19. get { return id; }
  20. set { id = value; }
  21.     }
  22. privateint pid;
  23. publicint Pid
  24.     {
  25. get { return pid; }
  26. set { pid = value; }
  27.     }
  28. public A(string name, string value, int id, int pid)
  29.     {
  30. this.name = name;
  31. this.value = value;
  32. this.id = id;
  33. this.pid = pid;
  34.     }
  35. }

然後例項化物件,賦值並放入一個ArrayList中

  1. ArrayList set = new ArrayList();
  2. set.Add(new A("子1""sdf", 3, 1));
  3. set.Add(new A("父1""sdf", 1, 0));
  4. set.Add(new A("子2""sdf", 5, 2));
  5. set.Add(new A("孫1""sdf", 4, 3));
  6. set.Add(new A("父2""sdf", 2, 0));

在手上有這樣的DataSet(DataTable)或者ArrayList情況下,我們希望能為TreeView設定DataSource後呼叫DataBind()方法即可完成資料繫結和顯示功能。

所以,我們要做的TreeView需要兩大功能:節點和其父子自動勾選和取消勾選,資料繫結