いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

TreeViewにてSelectedNodeChangedイベントが発生しないパターンについて (OnSelectedNodeChanged, Selectedプロパティ, Clickイベントみたいなもの)


以下、忘れない内にメモメモ。


ASP.NETのTreeViewには、SelectedNodeChangedイベントがあります。
このイベントはその名前の通り、選択ノードが変更された際にコールバックされます。


んで、このイベント、当然なのですが同じノードを2回以上連続で選択した場合は
発生しません。さらに、デスクトップアプリのツリーコントロールと違って
ASP.NETのTreeViewコントロールにはClickイベントみたいなのがありません。


(例) 初期表示→ノード(A)選択→SelectedNodeChanged発生→ノード(A)選択→イベント発生せず。


事情により、同じノードを選択された場合でもイベントが発生してもらわないと困ることになっていたので
ネットで情報を探したら、以下のページに解決方法が記述されていました。感謝。


具体的には、以下のようにPage_Loadの部分で

TreeView1.SelectedNode.Selected = false;

と一旦選択状態を解除することで解決できました。


上記のURLにて別の方が回答しているように

SelectedNodeChangedイベントハンドラ内にてノードのSelected=falseとする

方法を実行すると、毎回イベントは発生するのですが選択色が消えてしまいます。


選択色などの状態をそのままで、かつ、毎クリック時にSelectedNodeChangedイベントを
発生させるには、Page_Loadの中となります。


以下、サンプルコードです。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:TreeView ID="TreeView1" runat="server" ImageSet="Arrows" Width="222px" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">
            <HoverNodeStyle Font-Underline="True" ForeColor="#5555DD" />
            <Nodes>
                <asp:TreeNode Text="ルートノード" Value="ルートノード">
                    <asp:TreeNode Text="子ノード1" Value="子ノード1">
                        <asp:TreeNode Text="孫ノード1" Value="孫ノード1"></asp:TreeNode>
                    </asp:TreeNode>
                    <asp:TreeNode Text="子ノード2" Value="子ノード2">
                        <asp:TreeNode Text="孫ノード2" Value="孫ノード2"></asp:TreeNode>
                    </asp:TreeNode>
                    <asp:TreeNode Text="子ノード3" Value="子ノード3">
                        <asp:TreeNode Text="孫ノード3" Value="孫ノード3"></asp:TreeNode>
                    </asp:TreeNode>
                </asp:TreeNode>
            </Nodes>          
            <NodeStyle Font-Names="Tahoma" Font-Size="10pt" ForeColor="Black" 
                HorizontalPadding="5px" NodeSpacing="0px" VerticalPadding="0px" />
            <ParentNodeStyle Font-Bold="False" />
            <SelectedNodeStyle Font-Underline="True" ForeColor="White" BackColor="Blue"
                HorizontalPadding="0px" VerticalPadding="0px" />
        </asp:TreeView>
    </div>
    <asp:Panel ID="Panel1" runat="server">
        <asp:Label ID="Label1" runat="server" Text="Count:"></asp:Label>
        <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    </asp:Panel>
    </form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;

public partial class _Default : Page
{
    TreeNode _selectedNode;
    boolean _isFiredNodeChangeEvent;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            TextBox1.Text = 0.ToString();
        }
        else
        {
            //
            // このタイミングで、以下のコードを設定すると
            // 選択色を保持したまま、ノードのクリックで
            // 同じノードの再選択でも、カウントをアップすることが出来る。
            // (つまり、SelectedNodeChangedイベントが発生する。)
            //
            if (TreeView1.SelectedNode != null)
            {
                TreeView1.SelectedNode.Selected = false;
                _selectedNode = TreeView1.SelectedNode;
                _isFiredNodeChangeEvent = true;
            }
        }
    }

    protected void Page_LoadComplete(object sender, EventArgs e)
    {
        if (!_isFiredNodeChangeEvent)
        {
            _selectedNode.Selected = true;
        }
    }

    protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
    {
        var countString = TextBox1.Text;
        if (string.IsNullOrWhiteSpace(countString))
        {
            countString = 0.ToString();
        }

        int count;
        if (!int.TryParse(countString, out count))
        {
            count = -1;
        }

        TextBox1.Text = (++count).ToString();

        //
        // このタイミングで以下のコードを設定すると
        // ノードをクリックするたびに、カウントがアップするように
        // なるが、ノードの選択色が消えてしまう。
        //
        //TreeView1.SelectedNode.Selected = false;
    }
}

================================
過去の記事については、以下のページからご参照下さい。