我需要扩展treenode类,以便可以向每个节点添加自定义属性(正如webforms treenode不包括tag属性一样)。所以这是我的客户地址:
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值已经丢失,因为空构造函数返回一个没有任何值的节点。
非常感谢您的帮助。
最佳答案
这就是我想到的(专家,欢迎任何建议)。在代码后面实例化CustomTreeNode
s并通过setter设置属性。修改CustomTreeNode
类以将值持久化在viewstate中。自定义树视图的CreateNode
返回的节点将加载viewstate信息。
Treenode类:
[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文件(假设您的自定义控件是在程序集“foo”和命名空间“bar”中定义的):
<%@ 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;
}