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.

    Consultant freelance, 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

- Silverlight 3 : Communication et multicast par Kévin Gosse le il y a 10 heures et 4 minutes

- [Perso] Découvertes estivales : Linux (Part I) par Le blog de FremyCompany le il y a 12 heures et 46 minutes

- [Refactoring] ReSharper pour Visual Studio 2010 (Preview) par Thomas Jaskula le 07-04-2009, 00:50

- [Refactoring] Analyser vos exceptions avec ReSharper Exceptional par Thomas Jaskula le 07-03-2009, 23:36

- SharePoint 2007 : patterns & practices SharePoint Guidance par Philippe Sentenac [MVP SharePoint] le 07-03-2009, 09:56

- [Visual Studio 2010] Les tests cases c’est bien, mais je vais devoir tout réécrire ? par Etienne Margraff le 07-03-2009, 09:00

- MVP[Gribouillon].AddYear par The Grib's Lair [Sébastien PICAMELOT - MVP SharePoint] le 07-03-2009, 08:45

- Clinique INSIA - Projet de fin d’Etudes (Silverlight 3 MVVM et OutOfBrowser, WCF, TFS) - Part 1 par David REI le 07-02-2009, 23:38

- C’est la crise ? Bah pourquoi cramer du budget pub alors ? par Nix's Blog le 07-02-2009, 15:31

- Soyons MVP ! par TheSaib .NET blog le 07-02-2009, 12:15