2012-04-26 116 views
4

我需要擴展TreeNode類,以便可以將自定義屬性添加到每個節點(請參閱WebForms TreeNode不包含Tag屬性)。所以這是我CustomTreeNode:創建自定義TreeView/TreeNode

public class CustomTreeNode : TreeNode 
{ 

    public CustomTreeNode() 
    {    
    } 

    public CustomTreeNode(int nodeId, string nodeType) 
    { 
     NodeId = nodeId; 
     NodeType = nodeType; 
    } 

    public string NodeType { get; set; } 
    public int NodeId { get; set; } 
} 

如果我創建一個CustomTreeNode並將其添加到一個TreeView:

CustomTreeNode node = new CustomTreeNode(1, "CustomType");    
treeView.Nodes.Add(node); 

然後,我會得到一個鑄造例外執行下列操作:

CustomTreeNode selectedNode = (CustomTreeNode)TreeView.SelectedNode; 

因爲TreeView返回一個TreeNode,而不是一個CustomTreeNode。

我已經做了一些閱讀,看起來我需要擴展TreeView類,並重寫CreateNode()方法以返回CustomTreeNode而不是TreeNode。所以我創造了這個:

public class CustomTreeView : TreeView 
{ 
    protected override TreeNode CreateNode() 
    { 
     return new CustomTreeNode(); 
    } 
} 

的問題然而,CreateNode()不帶任何參數,所以你必須有呼籲CustomTreeNode類空構造。所以,當我創建上面的CustomTreeNode時,當我從CustomTreeView中獲取它時,nodeId和nodeType值已丟失,因爲空構造函數返回沒有任何值的節點。

任何幫助非常感謝。

回答

5

這是我想出了(專家,歡迎任何意見)。在您的代碼中實例化CustomTreeNode,並通過setter設置屬性。修改您的CustomTreeNode類以保留ViewState中的值。您的自定義樹視圖CreateNode返回的節點將加載ViewState信息。

樹節點類:

[DefaultProperty("Text")] 
[ToolboxData("<{0}:CustomTreeNode runat=server></{0}:CustomTreeNode>")] 
public class CustomTreeNode : TreeNode 
{ 
    private const int NODE_TYPE = 1; 
    private const int NODE_ID = 2; 

    public string NodeType { get; set; } 
    public int NodeId { get; set; } 

    protected override void LoadViewState(Object savedState) 
    { 
     if (savedState != null) 
     { 
      object[] myState = (object[])savedState; 
      if (myState[0] != null) 
       base.LoadViewState(myState[0]); 
      if (myState[NODE_TYPE] != null) 
       this.NodeType = (string)myState[NODE_TYPE]; 
      if (myState[NODE_ID] != null) 
       this.NodeId = (int)myState[NODE_ID]; 

     } 
    } 

    protected override Object SaveViewState() 
    { 
     object baseState = base.SaveViewState(); 
     object[] allStates = new object[3]; 
     allStates[0] = baseState; 
     allStates[NODE_TYPE] = this.NodeType; 
     allStates[NODE_ID] = this.NodeId; 

     return allStates; 
    } 
} 

的TreeView類:

[DefaultProperty("Text")] 
[ToolboxData("<{0}:CustomTreeView runat=server></{0}:CustomTreeView>")] 
public class CustomTreeView : TreeView 
{ 
    protected override TreeNode CreateNode() 
    { 
     // Tree node will get its members populated with the data from VIEWSTATE 
     return new CustomTreeNode(); 
    } 
} 

簡單的.aspx文件(假設您的自定義控制在裝配 「富」 與命名空間 「酒吧」 中定義:

<%@ Register TagPrefix="customControl" Assembly="Foo" Namespace="Bar" %> 

<customControl:CustomTreeView ID="sampleTree" 
    runat="server" onselectednodechanged="sampleTree_SelectedNodeChanged"></customControl:CustomTreeView> 
<asp:Label ID="lblSelectedNode" runat="server" ></asp:Label> 

代碼隱藏:

protected void Page_Load(object sender, EventArgs e) 
    { 
     if (!IsPostBack) 
     { 
      PopulateTree(); 
     } 
    } 

    private void PopulateTree() 
    { 
     sampleTree.Nodes.Clear(); 
     CustomTreeNode root = new CustomTreeNode(); 
     root.Value = "root node"; 

     sampleTree.Nodes.Add(root); 

     // Creating some fake nodes (you would of course be using real data) 
     for (int i = 0; i < 10; i++) 
     { 
      CustomTreeNode child = new CustomTreeNode(); 
      child.NodeId = i;    // Saved in ViewState 
      child.NodeType = "Type " + i; // Saved in ViewState 
      child.Value = child.NodeType; 
      root.ChildNodes.Add(child); 
     } 
    } 

    protected void sampleTree_SelectedNodeChanged(object sender, EventArgs e) 
    { 
     CustomTreeView cTreeView = (CustomTreeView) sender; 
     lblSelectedNode.Text = ((CustomTreeNode)cTreeView.SelectedNode).NodeType; 
    } 
+0

謝謝。這是非常有用和有用的知道。它工作完美。 – pedroAx 2012-04-26 09:35:49

+0

@Tung這是一篇很棒的文章。同時我閱讀了這篇文章,我正在閱讀這個鏈接:http://support.microsoft.com/kb/2527108。我實現了你的解決方案,但是我得到了這個錯誤:'錯誤6名稱空間'System.Web.UI.WebControls'中不存在類型或命名空間名'CustomTreeView'。我需要在aspx代碼中添加一些東西? – Ninita 2014-07-31 09:19:57

+1

@Ninita這實際上是一個例子中的錯誤。標籤前綴應該是通過頁面指令註冊的。如果你的控件是在名爲'Bar'的名爲'Foo'的程序集中定義的,那麼你可以在'Register'指令中設置'Assembly =「Foo」'和'Namespace =「Bar」'。我更新了這個例子 – Tung 2014-08-01 00:01:35

0

你可以在CustomTreeView類重載CreateNode

​​
+0

原諒我,我只是看到我的解決方案無法正常工作,因爲TreeNode沒有成員NodeId和NodeType。 – jahu 2012-04-26 08:25:42

+0

如果你認爲這是錯的,你爲什麼不刪除你的答案? – Breeze 2016-03-29 06:28:57