ASP.NET tree structure
This board has been so helpful in the past, thanks for all your responses and input. I've got a problem that we've come up with a few solutions for already, but I really don't like any of them. I'm hoping to get some new opinions.
We are migrating to ASP.NET for our content management systems, which are permission based. Our permissions are in tables are have a tree structure, like so:
permission table: permid (id, key), permission_name, permission_file, parent
Where 'parent' is the parent permission (if any). Currently in our legacy ASP system, we select all permissions that don't have parents (top level permissions), display as we loop through those, then select all the children, and recursively display a tree-like set of checkboxes. This works fine, of course, but it can potentially cost a lot of SQL calls. Additionally, in ASP.NET, we are using code-behind pages and are trying to keep all programming logic and layout seperate.
Is there any easy way to display a tree of checkboxes like below, given the table structure I've described above without using code (or minimal code) in the layout and using the minimal amout of SQL calls? Stored procedures are not necessarily out of the question, though preferably we don't want to use one (we haven't thought of a good way to use one anyway).
An example page would then look like:
 Manage Articles (top level)
----- Add Article (child)
----- Delete Article (child)
 Manage Galleries (top level)
----- Add Gallery (child)
----- Delete gallery (child)
Where  is a checkbox that an administrator can check, click [submit], and give a user the permissions he checked. In our legacy ASP, if they click a child permission, the system will check to make sure the corresponding parent permission(s) is (are) given as well.
Any ideas or comments are appreciated, even if they are alternatives to the framework I've layed out or even if you think we are doing it completely wrong.
If you're using SQL Server 2005 as the database look up "recursive queries", this will solve the SQL issue for you. Just 1 query to bring back the list.
We don't have 2005.
I'm thinking premature optimization or interface problem. Assume the worst case scenario for 50 items for which each incremental item is a child of the previous. So you would have the following:
[ ] Item 1 [ ] Item 2 [ ] Item 3 [ ] Item 4 . . .
In this case, you would need 50 calls to walk the hierarchy which isn't too bad for a content management system and setting permissions. First, 50 items is close to the maximum number of items I would display on one page anyways. If you have more items then you might want to categorize the permissions from a UI standpoint anyway, which spreads the database load out. If on the other hand you have 5 parents each with 10 children you need 6 calls to walk the hierarchy, which is substantially less.
Second, it's not like setting permissions is (should be) done all the time. The bulk of the work will be done when the system is first setup and after that there will be occasional maintenance. Most likely when the system is first setup, the site will be down because no one has rights to add/modify content.
It just a thought, but another avenue to explore is AJAX. You display the parents first and then by granting the parent permission you query for and display the immediate children. It might solve both potential issues in one shot.
AJAX might be a little too fancy for what we need. I think you are right on the speed issue: it's not an issue. Very seldom maintainence after initial setup.
The main issue I had (and I guess I should have made this more clear) is the actualy display element--how do we display this type of structure based on the table layout.
What we've come up with since I first posted is working really good: a recursive function that creates a bunch of TreeNodes and adds the top level TreeNodes to the TreeView. This is working fine, albeit with the multiple SQL calls.
The next issue is this: the TreeView renders as a table, which in some cases is fine, it makes semantic sense, but in other cases, it doesn't. For instance: navigation should be an unordered list, not a table. Any ideas?
AJAX might not be too fancy after all, for the Treeview has built-in support for it. Check its PopulateOnDemand and PopulateNodesFromClient properties.
PopulateOnDemand causes the treeview to build the tree in the TreeNodePopulate event. This event is called whenever a node is expanded and the PopulateOnDemand property is set to true. So instead of building the entire tree in Page_Load you can build the tree as needed.
If the PopulateNodesFromClient property is set to True as well the treeview will use its Ajax-capabilities to populate the tree without causing a postback. So it's quite easy to get some fancy schmancy AJAX functionality here.
As for navigation you can look at the Menu control. I am not sure what HTML it will render as default, but I think you can use templates to render it any way you want. As a worst case you can use the Repeater control, but you should check out the Menu first.