by WebSurfer
2014年10月20日 17:21
TreeView の SelectedNodeStyle-ImageUrl(正確には TreeView.SelectedNodeStyle プロパティで取得できる TreeNodeStyle オブジェクトの ImageUrl プロパティ)にイメージの URL を設定しても無視されます。
例えば、上の画像のように、選択されたノード(上の画像の例では Topic 1.0.1)の左隣に表示される三角形は青、それ以外は白抜きの三角形にしたいとします。
その場合、NodeStyle-ImageUrl には白抜きの三角形、SelectedNodeStyle-ImageUrl に青の三角形のイメージを設定するとよさそうですが、実際にそのように設定して試すと SelectedNodeStyle-ImageUrl の方は無視されます(ノードを選択しても白抜きの三角形のまま変わりません)。
これは stackoverflow のページ およびそのページにあるリンク先に書いてあるようにバグのようです。ASP.NET 4.5 でも修正されていません。
では、どうすれば選択されたノードの左隣に表示されるイメージを、期待した通り上の画像のような青三角のイメージにできるかですが、その方法を以下に書きます。
サンプルとして、MSDN ライブラリの TreeView.SelectedNodeStyle プロパティ にあるコードに手を加えてみました。
まず、選択されてないノード用のイメージですが、各 TreeNodeStyle の ImageUrl プロパティに白抜き三角のイメージの URL を静的に設定します。
SelectedNodeStyle-ImageUrl は静的に設定しても無視されるので、TreeView の SelectedNodeChanged イベントのハンドラで SelectedNode の ImageUrl に青三角のイメージの URL を動的に設定します。
ただし、設定しっぱなしではノードの選択を変更した時に前に選択したノードのイメージが青三角のまま元に戻りません。ノードの選択が変更された場合は、前に選択されたノードのイメージを白抜き三角イメージの URL に書き戻すコードが必要になります。
そのため、選択したノードの ValuePath を ViewState に保持しておき、ノードの選択が変更になった場合は ViewState に保持したパス情報を元に前に選択されたノードを探し、その ImageUrl を書き換えます。その後、新たに選択されたノードの ValuePath を ViewState に保存します。
ちなみに、ValuePath はルートノードから選択されたノードまでの Value をつなげた文字列になります。例えば Topic 1.0.1 を選択した場合は "Table of Contents/Chapter One/Section 1.0/Topic 1.0.1" になります(サンプルコードでは Value プロパティを明示的に設定してないので Text プロパティの値が使用されます)。
修正後のコードは以下の通りです。実際に動かして試すことができるよう 実験室 にアップしましたので、興味がありましたら試してみてください。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Select_Change(Object sender, EventArgs e)
{
Message.Text =
"You selected: " + LinksTreeView.SelectedNode.Text;
// これだけではダメ。イメージは元に戻らない。
LinksTreeView.SelectedNode.ImageUrl =
"~/Images/right_selected.gif";
// 前に選択されたノードのイメージを元に戻す。
string valuePath =
(string)ViewState["TreeNodeValuePath"];
if (!String.IsNullOrEmpty(valuePath))
{
LinksTreeView.FindNode(valuePath).ImageUrl =
"~/Images/right.gif";
}
ViewState["TreeNodeValuePath"] =
LinksTreeView.SelectedNode.ValuePath;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>TreeView SelectedNodeStyle Example</title>
</head>
<body>
<form id="form1" runat="server">
<h3>TreeView SelectedNodeStyle Example</h3>
<asp:TreeView id="LinksTreeView"
Font-Names= "Arial"
ForeColor="Blue"
SelectedNodeStyle-ForeColor="Green"
SelectedNodeStyle-VerticalPadding="0"
OnSelectedNodeChanged="Select_Change"
runat="server">
<LevelStyles>
<asp:TreeNodeStyle ChildNodesPadding="10"
ImageUrl="~/Images/right.gif"
Font-Bold="true"
Font-Size="12pt"
ForeColor="DarkGreen"/>
<asp:TreeNodeStyle ChildNodesPadding="5"
ImageUrl="~/Images/right.gif"
Font-Bold="true"
Font-Size="10pt"/>
<asp:TreeNodeStyle ChildNodesPadding="5"
ImageUrl="~/Images/right.gif"
Font-UnderLine="true"
Font-Size="10pt"/>
<asp:TreeNodeStyle ChildNodesPadding="10"
ImageUrl="~/Images/right.gif"
Font-Size="8pt"/>
</LevelStyles>
<Nodes>
<asp:TreeNode Text="Table of Contents"
SelectAction="None">
<asp:TreeNode Text="Chapter One">
<asp:TreeNode Text="Section 1.0">
<asp:TreeNode Text="Topic 1.0.1" />
<asp:TreeNode Text="Topic 1.0.2" />
<asp:TreeNode Text="Topic 1.0.3" />
</asp:TreeNode>
<asp:TreeNode Text="Section 1.1">
<asp:TreeNode Text="Topic 1.1.1"/>
<asp:TreeNode Text="Topic 1.1.2" />
<asp:TreeNode Text="Topic 1.1.3" />
<asp:TreeNode Text="Topic 1.1.4" />
</asp:TreeNode>
</asp:TreeNode>
<asp:TreeNode Text="Chapter Two">
<asp:TreeNode Text="Section 2.0">
<asp:TreeNode Text="Topic 2.0.1" />
<asp:TreeNode Text="Topic 2.0.2" />
</asp:TreeNode>
</asp:TreeNode>
</asp:TreeNode>
<asp:TreeNode Text="Appendix A" />
<asp:TreeNode Text="Appendix B" />
<asp:TreeNode Text="Appendix C" />
</Nodes>
</asp:TreeView>
<br /><br />
<asp:Label id="Message" runat="server"/>
</form>
</body>
</html>