Как мне зафиксировать событие щелчка по выбранному узлу TreeView? Он не запускает SelectedNodeChanged, поскольку выбор явно не изменился, но какое событие я могу поймать, чтобы знать, что выбранный узел был нажат?
ОБНОВИТЬ: Когда у меня будет время, мне придется погрузиться в недра элемента управления TreeView и выяснить, что и где он обрабатывает события щелчка, и создать подкласс TreeView, чтобы открыть новое событие OnSelectedNodeClicked.
Я, вероятно, сделаю это во время рождественских каникул и доложу о результатах.
ОБНОВИТЬ: Я придумал решение ниже подклассов элемента управления TreeView.





Самый простой способ - если он не мешает остальной части вашего кода - просто установить узел как не выбранный в методе SelectedNodeChanged.
protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e){
// Do whatever you're doing
TreeView1.SelectedNode.Selected = false;
}
Вы всегда можете использовать событие MouseDown или MouseUp и проверить, является ли он выбранным узлом.
На данный момент меня интересует элемент управления ASP.NET TreeView. Я предполагаю, что вы, возможно, имеете в виду элементы управления WinForm или WPF? Или вы имеете в виду события DOM? Я действительно не хочу углубляться в написание клиентского кода для этого.
Сохраните то, что выбрано, и используйте код в обработчике событий Page_Load, чтобы сравнить то, что выбрано, с тем, что вы сохранили. Page_Load вызывается для каждой обратной публикации, даже если выбранное значение не меняется, в отличие от SelectedNodeChanged.
Пример
альтернативный текст http://smithmier.com/TreeViewExample.png
html
<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
Когда вы добавляете узлы в дерево в событии _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 уже настроен. Проблема в том, что я не знаю, вызвал ли выбор уже выбранного узла обратную передачу.
После довольно продолжительного периода у меня наконец-то появилось время, чтобы изучить, как создать подкласс 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?
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TreeView1.SelectedNode.Selected = false;
}
}
работает на меня
Я хочу, чтобы выбранный узел отображался как выбранный, поэтому это не помогает
C#:
TreeNode node = TreeTypes.FindNode(obj.CustomerTypeId.ToString());
TreeTypes.Nodes[TreeTypes.Nodes.IndexOf(node)].Select();
У меня есть проблема, похоже, но я ее решил!
в коде на стороне сервера:
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>
Я использую свойство ShowCheckBox и свойство Checked, чтобы «выделить» выбранный элемент.
Когда возникает событие SelectedNodeChanged:
ShowCheckBox и свойства Checked для старого выбранного, а для свойства ShowCheckBox и свойства Checked для нового выбранного.myTreeView.SelecteNode.Selected = false
К сожалению, я все еще хочу, чтобы выбранный узел был выбран на самом деле.