Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Atteint de JavaScriptite Aiguë [Cyril Durand]

Expert ASP.net Ajax et WCF, Cyril Durand parle dans son blog de point techniques sur ASP.net, ASP.net Ajax, JavaScript, WCF et .net en général. Cyril est également consultant indépendant, n'hésitez pas à le contacter pour de l'assistance sur vos projets

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    N'hésitez pas à me contacter pour vos projets .net : architecture, accompagnement, formation, ...

    View Cyril Durand's profile on LinkedIn
    hit counters


    Expertise Commerce server et BizTalk

Un datasource hierarchique pour binder vos treeview / menu

ASP.net 2.0 possède les contrôles Menu et Treeview. Ces contrôles sont généralement méconnus par les développeurs ASP.net pour plusieurs raisons :

  • On a rarement besoin de ce genre de contrôle ;
  • Les exemples d'utilisations sont toujours simples, association avec un XmlDataSource ou SiteMapDataSource, ce qui correspond rarement à la réalité, dès que l'on veut faire quelque chose de précis avec ces contrôles cela se complique et les exemples sont rares;
  • Le code HTML généré est horrible.

Au niveau du code HTML, les CSS Friendly Control Adapters améliorent grandement les choses, la démo du contrôle treeview est particulièrement bluffante : le code HTML généré passe de 49ko à 18ko tout simplement en utilisant HTML correctement avec une bonne sémantique.

Pour le second point, les exemples que l'on trouve utilisent généralement un SiteMapDataSource : du coup on se retrouve avec un exemple du genre :

<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1"> </asp:TreeView> <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />

Mais dans la vraie vie, on a des besoins bien plus complexes. Comment faire pour, par exemple, afficher une arborescence de dossier ? La plupart des exemples vont rajouter des noeuds directement au niveau de la propriété Nodes du treeview :

' sample from : http://aspnet.4guysfromrolla.com/articles/083006-1.aspx Private Const VirtualImageRoot = "~/Images/Public/" Private Sub PopulateTree() 'Populate the tree based on the subfolders of the specified VirtualImageRoot Dim rootFolder As New DirectoryInfo(Server.MapPath(VirtualImageRoot)) Dim root As TreeNode = AddNodeAndDescendents(rootFolder, Nothing) 'Add the root to the TreeView PictureTree.Nodes.Add(root) End Sub Private Function AddNodeAndDescendents(ByVal folder As DirectoryInfo, ByVal parentNode As TreeNode) As TreeNode 'Add the TreeNode, displaying the folder's name and storing the full path to the folder as the value... Dim virtualFolderPath As String If parentNode Is Nothing Then virtualFolderPath = VirtualImageRoot Else virtualFolderPath = parentNode.Value & folder.Name & "/" End If Dim node As New TreeNode(folder.Name, virtualFolderPath) 'Recurse through this folder's subfolders Dim subFolders As DirectoryInfo() = folder.GetDirectories() For Each subFolder As DirectoryInfo In subFolders Dim child As TreeNode = AddNodeAndDescendents(subFolder, node) node.ChildNodes.Add(child) Next Return node 'Return the new TreeNode End Function

Cette solution ne me convient pas ! Ce code n'a rien à faire dans la couche d'affichage, il devrait être dans la couche logique. Le plus simple serait de faire comme les classiques contrôles, c'est à dire de pouvoir assigner un objet à la propriété DataSource du treeview. Mais que lui passer comme DataSource ? Il faudrait une datasource hiérarchique ! C'est exactement le but des interfaces IHierarchicalEnumerable et IHierarchyData.

Voici d'ailleurs comment elles sont définies :

public interface IHierarchicalEnumerable : IEnumerable { // Methods IHierarchyData GetHierarchyData(object enumeratedItem); } public interface IHierarchyData { // Methods IHierarchicalEnumerable GetChildren(); IHierarchyData GetParent(); // Properties bool HasChildren { get; } object Item { get; } string Path { get; } string Type { get; } }

Un objet implémentant l'interface IHierarchicalEnumerable doit retourner des objets implémentant IHierarchyData qui eux même peuvent returner des enfants de type IHierarchicalEnumerable.

On peut alors binder notre treeview avec notre objet implémentant IHierarchicalEnumerable ! Vous pouvez retrouver sur aspfr.com un exemple d'utilisation de cette interface qui vous permettra d'afficher le contenu d'un répertoire dans un treeview :

L'interface IHierarchicalEnumerable - bindez vos menu/treeview avec votre propre source de donnée

Cet exemple vous permettra d'écrire :

protected void Page_Load(object sender, EventArgs e) { // on bind notre treeview avec les fichiers/dossier contenu dans le dossier d:/www/ tv1.DataSource = new FileSystem(@"d:\www\", true); tv1.DataBind(); }
<asp:TreeView ID="tv1" runat="server" ImageSet="XPFileExplorer" NodeIndent="15" ExpandDepth="1" EnableViewState="false"> <ParentNodeStyle Font-Bold="False" /> <HoverNodeStyle Font-Underline="True" ForeColor="#6666AA" /> <SelectedNodeStyle BackColor="#B5B5B5" Font-Underline="False" HorizontalPadding="0px" VerticalPadding="0px" /> <NodeStyle Font-Names="Tahoma" Font-Size="8pt" ForeColor="Black" HorizontalPadding="2px" NodeSpacing="0px" VerticalPadding="2px" /> <DataBindings> <asp:TreeNodeBinding TextField="Name" /> </DataBindings> </asp:TreeView>

Ou alors en utilisant directement FileSystemDataSource, contrôle héritant de HierarchicalDataSourceControl

<asp:TreeView ID="tv1" runat="server" ImageSet="XPFileExplorer" NodeIndent="15" ExpandDepth="1" DataSourceID="fsds1" EnableViewState="false"> <ParentNodeStyle Font-Bold="False" /> <HoverNodeStyle Font-Underline="True" ForeColor="#6666AA" /> <SelectedNodeStyle BackColor="#B5B5B5" Font-Underline="False" HorizontalPadding="0px" VerticalPadding="0px" /> <NodeStyle Font-Names="Tahoma" Font-Size="8pt" ForeColor="Black" HorizontalPadding="2px" NodeSpacing="0px" VerticalPadding="2px" /> <DataBindings> <asp:TreeNodeBinding TextField="Name" /> </DataBindings> </asp:TreeView> <test:FileSystemDataSource runat="server" id="fsds1" rootPath="d:/www/" />

Vous pouvez retrouver un autre exemple d'utilisation de l'interface IHierarchicalEnumerable ici : Create a Hierarchical Data Source for the TreeView and Menu control.

Posted: mercredi 27 juin 2007 00:19 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

gpommier a dit :

Excellent !

# juin 27, 2007 18:28
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- TechDays Paris 2012 : Session pleinière jour 3 par Blog Technique de Romelard Fabrice le il y a 17 heures et 15 minutes

- Mishra Reader : un lecteur RSS très Zune Style en Open Source ! par Cyril Sansus le il y a 19 heures et 48 minutes

- [framework 4] Les Tasks et le Thread UI par Fathi Bellahcene le 02-09-2012, 00:33

- Workflow Foundation 3 a un pied dans la tombe par Blog de Jérémy Jeanson le 02-08-2012, 22:15

- TechDays Paris 2012 : Nouvelles tendances du poste de travail - Bring Your own PC par Blog Technique de Romelard Fabrice le 02-08-2012, 19:42

- TechDays Paris 2012 : System Center Service Manager 2012 Vue d’ensemble par Blog Technique de Romelard Fabrice le 02-08-2012, 17:32

- TechDays Paris 2012 : Pleinière second jour par Blog Technique de Romelard Fabrice le 02-08-2012, 16:23

- TechDays Paris 2012 : Retour d'expérience sur la mise en place d'un Cloud Privé par Blog Technique de Romelard Fabrice le 02-08-2012, 16:04

- TechDays Paris 2012 : Comment SharePoint a sauvé mes TechDays par Blog Technique de Romelard Fabrice le 02-07-2012, 23:59

- Perspective 3.0 pour Silverlight 5.0 par Perspective le 02-07-2012, 22:39