ASP.NET TreeView 和选择选定的节点
Posted
技术标签:
【中文标题】ASP.NET TreeView 和选择选定的节点【英文标题】:ASP.NET TreeView and Selecting the Selected Node 【发布时间】:2008-09-20 04:54:00 【问题描述】:如何捕获单击 TreeView 的选定节点的事件? 它不会触发 SelectedNodeChanged,因为选择显然没有改变,但是我可以捕捉到什么事件,所以我知道选择的节点被点击了?
更新: 当我有时间时,我将不得不深入了解 TreeView 控件的内部,挖掘它处理单击事件的内容和位置,并将 TreeView 子类化以公开一个新事件 OnSelectedNodeClicked。
我可能会在圣诞节假期这样做,然后我会报告结果。
更新: 我在下面提出了一个解决方案,将 TreeView 控件子类化。
【问题讨论】:
【参考方案1】:最简单的方法 - 如果它不干扰您的代码的其余部分 - 只需将节点设置为未在 SelectedNodeChanged 方法中选择。
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
// Do whatever you're doing
TreeView1.SelectedNode.Selected = false;
【讨论】:
不幸的是,我仍然希望看到所选节点被实际选中【参考方案2】:经过漫长的一段时间后,我终于有时间研究如何对 TreeView 进行子类化以处理被单击的选定节点。
这是我的解决方案,它公开了一个新事件 SelectedNodeClicked,您可以从页面或任何地方处理该事件。 (如果需要,重构为 C# 是一项简单的任务)
Imports System.Web.UI
Imports System.Web
Public Class MyTreeView
Inherits System.Web.UI.WebControls.TreeView
Public Event SelectedNodeClicked As EventHandler
Private Shared ReadOnly SelectedNodeClickEvent As Object
Private Const CurrentValuePathState As String = "CurrentValuePath"
Protected Property CurrentValuePath() As String
Get
Return Me.ViewState(CurrentValuePathState)
End Get
Set(ByVal value As String)
Me.ViewState(CurrentValuePathState) = value
End Set
End Property
Friend Sub RaiseSelectedNodeClicked()
Me.OnSelectedNodeClicked(EventArgs.Empty)
End Sub
Protected Overridable Sub OnSelectedNodeClicked(ByVal e As EventArgs)
RaiseEvent SelectedNodeClicked(Me, e)
End Sub
Protected Overrides Sub OnSelectedNodeChanged(ByVal e As System.EventArgs)
MyBase.OnSelectedNodeChanged(e)
' Whenever the Selected Node changed, remember its ValuePath for future reference
Me.CurrentValuePath = Me.SelectedNode.ValuePath
End Sub
Protected Overrides Sub RaisePostBackEvent(ByVal eventArgument As String)
' Check if the node that caused the event is the same as the previously selected node
If Me.SelectedNode IsNot Nothing AndAlso Me.SelectedNode.ValuePath.Equals(Me.CurrentValuePath) Then
Me.RaiseSelectedNodeClicked()
End If
MyBase.RaisePostBackEvent(eventArgument)
End Sub
End Class
【讨论】:
然后把它放到 ascx 控件中?【参考方案3】:存储所选内容并使用 Page_Load 事件处理程序中的代码将所选内容与您存储的内容进行比较。与 SelectedNodeChanged 不同,即使所选值不变,每次回发都会调用 Page_Load。
例子
alt text http://smithmier.com/TreeViewExample.png
<form id="form1" runat="server">
<div>
<asp:TreeView ID="TreeView1" runat="server" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged"
ShowLines="True">
<Nodes>
<asp:TreeNode Text="Root" Value="Root">
<asp:TreeNode Text="RootSub1" Value="RootSub1"></asp:TreeNode>
<asp:TreeNode Text="RootSub2" Value="RootSub2"></asp:TreeNode>
</asp:TreeNode>
<asp:TreeNode Text="Root2" Value="Root2">
<asp:TreeNode Text="Root2Sub1" Value="Root2Sub1">
<asp:TreeNode Text="Root2Sub1Sub1" Value="Root2Sub1Sub1"></asp:TreeNode>
</asp:TreeNode>
<asp:TreeNode Text="Root2Sub2" Value="Root2Sub2"></asp:TreeNode>
</asp:TreeNode>
</Nodes>
</asp:TreeView>
<asp:Label ID="Label1" runat="server" Text="Selected"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Label ID="Label2" runat="server" Text="Label"></asp:Label></div>
</form>
C#
protected void Page_Load(object sender, EventArgs e)
if(TreeView1.SelectedNode!=null && this.TextBox1.Text == TreeView1.SelectedNode.Value.ToString())
Label2.Text = (int.Parse(Label2.Text) + 1).ToString();
else
Label2.Text = "0";
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
this.TextBox1.Text = TreeView1.SelectedNode.Value.ToString();
【讨论】:
不幸的是,这无济于事,因为任何事情都可能导致回发。我仍然无法判断 SelectedNode 是否被点击【参考方案4】:当您在 _TreeNodePopulate() 事件中向树添加节点时,请在节点上设置 .SelectionAction 属性。
TreeNode newCNode;
newCNode = new TreeNode("New Node");
newCNode.SelectAction = TreeNodeSelectAction.Select;
//now you can set the .NavigateUrl property to call the same page with some query string parameter to catch in the page_load()
newCNode.NavigateUrl = "~/ThisPage.aspx?args=" + someNodeAction
RootNode.ChildNodes.Add(newCNode);
【讨论】:
SelectAction 已设置。问题还是不知道是不是选择了一个已经选中的节点导致了回发。【参考方案5】:c#:
TreeNode node = TreeTypes.FindNode(obj.CustomerTypeId.ToString());
TreeTypes.Nodes[TreeTypes.Nodes.IndexOf(node)].Select();
【讨论】:
【参考方案6】:protected void Page_Load(object sender, EventArgs e)
if (!IsPostBack)
TreeView1.SelectedNode.Selected = false;
为我工作
【讨论】:
我希望选中的节点实际显示为选中,所以这无济于事【参考方案7】:您始终可以使用 MouseDown 或 MouseUp 事件并检查它是否是选定的节点。
【讨论】:
我现在关心的是 ASP.NET TreeView 控件。我假设您可能指的是 WinForm 或 WPF 控件?还是您指的是 DOM 事件?我真的不想为此深入研究编写一些客户端代码的脚本。【参考方案8】:我使用ShowCheckBox
属性和Checked 属性来“突出显示”所选项目。
当SelectedNodeChanged
事件引发时:
-
我将旧选择的
ShowCheckBox
属性和Checked
属性设置为false,并将新选择的ShowCheckBox
属性和Checked
属性设置为true。
我将所选节点用于任何操作
最后,我取消选中选中的项目:
myTreeView.SelecteNode.Selected = false
【讨论】:
【参考方案9】:我有一个问题,但我解决了!
在服务器端代码中:
protected void MainTreeView_SelectedNodeChanged(object sender, EventArgs e)
ClearTreeView();
MainTreeView.SelectedNode.Text = "<span class='SelectedTreeNodeStyle'>" + MainTreeView.SelectedNode.Text + "</span>";
MainTreeView.SelectedNode.Selected = false;
public void ClearTreeView()
for (int i = 0; i < MainTreeView.Nodes.Count; i++)
for(int j=0;j< MainTreeView.Nodes[i].ChildNodes.Count;j++)
ClearNodeText(MainTreeView.Nodes[i].ChildNodes[j]);
ClearNodeText(MainTreeView.Nodes[i]);
public void ClearNodeText(TreeNode tn)
tn.Text = tn.Text.Replace("<span class='SelectedTreeNodeStyle'>", "").Replace("</span>", "");
在客户端代码中:
<style type="text/css">
.SelectedTreeNodeStyle font-weight: bold;
</style>
【讨论】:
以上是关于ASP.NET TreeView 和选择选定的节点的主要内容,如果未能解决你的问题,请参考以下文章
如何在C#中从Treeview的选定节点获取下一个直接节点?