Ano, za to bych se přimlouval - můžu poskytnout hotovou komponentu, kterou používáme zde na VbNetu. Tento kód dejte do složky App_Code. Je to tzv. Control Adapter - přepisuje chování komponenty TreeView, která kromě toho, že ve výchozím stavu generuje do stránky naprosto šílené HTML, tak si i sama pamatuje stav rozkliknutí a ukládá ho do cookies. Control adapter slouží k tomu, abychom si sami mohli přesně říci, jaké HTML se má do stránky generovat. Upozorňuji, že nebude fungovat veškerá funkcionalita TreeView, ale to, co je potřeba, by jít mělo.
Imports Microsoft.VisualBasic
Namespace VbNet
Public Class IntelligentTreeViewAdapter
Inherits System.Web.UI.WebControls.Adapters.HierarchicalDataBoundControlAdapter
Private nodeIndex As Integer = 0
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
Me.Control.DataBind()
'zaregistrovat skript
If Not Me.Page.ClientScript.IsClientScriptBlockRegistered("TreeViewClientScript") Then
Me.Page.ClientScript.RegisterClientScriptBlock(Me.Page.GetType, "TreeViewClientScript", _
"function getCookie(key) { // získat hodnotu cookie" & vbCrLf & _
" var cookies = document.cookie.split(';');" & vbCrLf & _
" for (var i = 0; i < cookies.length; i++) {" & vbCrLf & _
" while ((cookies[i].length > 0) && (cookies[i].charAt(0) == ' ')) cookies[i] = cookies[i].substring(1);" & vbCrLf & _
" if (cookies[i].toLowerCase().indexOf(key.toLowerCase() + '=') == 0) " & vbCrLf & _
" return unescape(cookies[i].substring(key.length + 1));" & vbCrLf & _
" }" & vbCrLf & _
" return '';" & vbCrLf & _
"}" & vbCrLf & _
"function TreeViewExpandCollapse(id, imageName, listName, expandedUrl, collapsedUrl, expandedAlt, collapsedAlt) {" & vbCrLf & _
" // rozbalí nebo sbalí položku menu" & vbCrLf & _
" arr = getCookie('menuState').split('_');" & vbCrLf & _
" if (document.getElementById(listName).style.display == 'none') {" & vbCrLf & _
" document.getElementById(listName).style.display = '';" & vbCrLf & _
" document.getElementById(imageName).src = expandedUrl;" & vbCrLf & _
" document.getElementById(imageName).alt = expandedAlt;" & vbCrLf & _
" document.getElementById(imageName).parentNode.parentNode.className = '';" & vbCrLf & _
" for (var i = 0; i < arr.length; i++)" & vbCrLf & _
" if (arr[i] == id) arr[i] = null;" & vbCrLf & _
" } else {" & vbCrLf & _
" document.getElementById(listName).style.display = 'none';" & vbCrLf & _
" document.getElementById(imageName).src = collapsedUrl;" & vbCrLf & _
" document.getElementById(imageName).alt = collapsedAlt;" & vbCrLf & _
" document.getElementById(imageName).parentNode.parentNode.className = 'final';" & vbCrLf & _
" arr[arr.length] = id;" & vbCrLf & _
" }" & vbCrLf & _
" document.cookie = 'menuState=' + arr.join('_');" & vbCrLf & _
"}", True)
End If
End Sub
Protected Overrides Sub RenderBeginTag(ByVal writer As System.Web.UI.HtmlTextWriter)
'vykreslit počáteční element menu
writer.WriteBeginTag("ul")
If Not String.IsNullOrEmpty(Control.CssClass) Then writer.WriteAttribute("class", Control.CssClass)
writer.Write(HtmlTextWriter.TagRightChar)
writer.Indent += 1
End Sub
Protected Overrides Sub RenderContents(ByVal writer As System.Web.UI.HtmlTextWriter)
'vykreslit obsah menu
nodeIndex = 0
Dim tv As TreeView = CType(Me.Control, TreeView)
For Each n As TreeNode In tv.Nodes
writer.WriteLine()
RenderNode(n, writer, tv)
Next
End Sub
Private Sub RenderNode(ByRef node As TreeNode, ByRef writer As System.Web.UI.HtmlTextWriter, ByRef tv As TreeView)
'vykreslit jednotlivé položky menu
writer.WriteBeginTag("li")
'obrázek podle toho, jestli je položka zabalená nebo rozbalená
If node.ChildNodes.Count > 0 Then
If Me.Page.Request.Cookies("menuState") IsNot Nothing AndAlso ("_" & Me.Page.Request.Cookies("menuState").Value & "_").Contains("_" & nodeIndex & "_") Then
writer.WriteAttribute("class", "final")
End If
writer.Write(HtmlTextWriter.TagRightChar)
writer.WriteBeginTag("a")
writer.WriteAttribute("href", "javascript:TreeViewExpandCollapse(" & nodeIndex & ",'" & tv.ClientID & "_img" & nodeIndex & "','" & tv.ClientID & "_node" & nodeIndex & "','" & Me.Page.ResolveClientUrl(tv.ExpandImageUrl) & "','" & Me.Page.ResolveClientUrl(tv.CollapseImageUrl) & "','" & tv.ExpandImageToolTip.Replace("'", "") & "','" & tv.CollapseImageToolTip.Replace("'", "") & "');")
writer.Write(HtmlTextWriter.TagRightChar)
writer.WriteBeginTag("img")
If Me.Page.Request.Cookies("menuState") IsNot Nothing AndAlso ("_" & Me.Page.Request.Cookies("menuState").Value & "_").Contains("_" & nodeIndex & "_") Then
writer.WriteAttribute("src", Me.Page.ResolveClientUrl(tv.CollapseImageUrl))
writer.WriteAttribute("alt", tv.CollapseImageToolTip)
node.Expanded = False
Else
Page.Response.Cookies("menuState").Value = ""
Page.Response.Cookies("menuState").Expires = Now.AddMonths(1)
writer.WriteAttribute("src", Me.Page.ResolveClientUrl(tv.ExpandImageUrl))
writer.WriteAttribute("alt", tv.ExpandImageToolTip)
node.Expanded = True
End If
writer.WriteAttribute("style", "border: none; vertical-align: middle;")
writer.WriteAttribute("id", tv.ClientID & "_img" & nodeIndex)
writer.Write(HtmlTextWriter.SelfClosingTagEnd)
writer.WriteEndTag("a")
Else
writer.WriteAttribute("class", "final")
writer.Write(HtmlTextWriter.TagRightChar)
writer.WriteBeginTag("img")
writer.WriteAttribute("src", Me.Page.ResolveClientUrl("~/App_Themes/" & Me.Page.Theme & "/images/non_expandable.gif"))
writer.WriteAttribute("alt", " ")
writer.Write(HtmlTextWriter.SelfClosingTagEnd)
End If
'text položky v odkazu
writer.Write(" ")
writer.WriteBeginTag("a")
writer.WriteAttribute("href", Me.Page.ResolveClientUrl(node.NavigateUrl))
writer.WriteAttribute("title", node.ToolTip)
writer.Write(HtmlTextWriter.TagRightChar)
writer.Write(node.Text)
writer.WriteEndTag("a")
If node.ChildNodes.Count > 0 Then
'vykreslit vnožené položky
writer.Indent += 1
writer.WriteLine()
writer.WriteBeginTag("ul")
writer.WriteAttribute("id", tv.ClientID & "_node" & nodeIndex)
If Not node.Expanded.Value Then writer.WriteAttribute("style", "display:none;")
writer.Write(HtmlTextWriter.TagRightChar)
writer.Indent += 1
For Each n As TreeNode In node.ChildNodes
writer.WriteLine()
RenderNode(n, writer, tv)
Next
writer.Indent -= 1
writer.WriteLine()
writer.WriteEndTag("ul")
writer.Indent -= 1
writer.WriteLine()
End If
writer.WriteEndTag("li")
nodeIndex += 1
End Sub
Protected Overrides Sub RenderEndTag(ByVal writer As System.Web.UI.HtmlTextWriter)
'vykreslit koncový element menu
writer.Indent -= 1
writer.WriteLine()
writer.WriteEndTag("ul")
writer.WriteLine()
End Sub
End Class
End Namespace
Výhodou je, že můžete použít stávající kód tak, jak ho máte, prostě používáte TreeView, akorát se bude chovat trochu jinak - vyrenderuje hezčí HTML a bude si pamatovat stav rozbalení a zabalení jednotlivých položek. Aby se Control Adapter použil, přidejte do projektu složku App_Browsers a do ní umístěte nový soubor s příponou .browser a s obsahem:
<browsers>
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.TreeView" adapterType="VbNet.IntelligentTreeViewAdapter" />
</controlAdapters>
</browser>
</browsers>
|