I build something like this with native .net ..
And first let me say this..
If you trying to build a hierarchy..
You will need that.. a function like that to build your folder list.
I connected myn to a database and had the ability to right click and add folders and objects..
But the core of the process was recursive function to load the folder hierarchy from the database.
Then as far as adding MonoX..
Your going to need to code a custom web part.. well dont tech need too but I would..
and then treeview .. i had some problems getting this to work originally with MonoX some time ago that since then I think was fixed if not im sure the post is somewhere on the forums to how to get it to work.
But use a Tree view to handle the folder display, will work nice and allow you to add your own objects under the folders.
You may want to even look into whats available in Jquery.
I also would use two asp.net update panels.
One to display the folders/objects, and one to display the content when clicking on the folders/objects.
I just grabbed some old sample code i wrote to do the database functions..
only to be used as ref.. no way it will compile but it will point you in the right direction to how to store a hiarchy structure inside the database..
public void GetCategory()
{
QueryTreeView.Nodes.Clear();
DataSet PrSet = PDataset("SELECT Q_CATEGORY_ID, Q_PARENT_ID, Q_CATEGORY_NAME FROM Categories ORDER BY Q_PARENT_ID");
foreach (DataRow dr in PrSet.Tables[0].Rows)
{
if ((int)dr["Q_PARENT_ID"] == 0)
{
TreeNode tnParent = new TreeNode();
tnParent.Text = dr["Q_CATEGORY_NAME"].ToString();
tnParent.Name = dr["Q_CATEGORY_ID"].ToString();
//Cmd is asigned to the node tag.
tnParent.Tag = QuerysMenuCmd.CategorySelect;
tnParent.Collapse();
//GET ALL QUERYS
DataContext MyDataContext = new DataContext(GConnectionString);
DataTable MyDataTable = new DataTable();
MyDataTable = MyDataContext.GetCategoryQuery(dr["Q_CATEGORY_ID"]);
foreach (DataRow Item in MyDataTable.Rows)
{
TreeNode MyNode = new TreeNode();
MyNode.Name = Item["QUERY_ID"].ToString();
MyNode.Text = Item["QUERY_NAME"].ToString();
//Cmd is asigned to the node tag.
MyNode.Tag = QuerysMenuCmd.OpenQuery;
MyNode.StateImageIndex = 1;
tnParent.Nodes.Add(MyNode);
}
QueryTreeView.Nodes.Add(tnParent);
FillChild(tnParent, dr["Q_CATEGORY_ID"].ToString());
}
}
}
public void SelectCategory(int CategoryId)
{
QueryTreeView.SelectedNode = GetNode(CategoryId, QueryTreeView.Nodes);
QueryTreeView.Select();
}
public int FillChild(TreeNode parent, string CategoryId)
{
DataSet ds = PDataset("SELECT Q_CATEGORY_ID, Q_PARENT_ID, Q_CATEGORY_NAME FROM Categories WHERE Q_PARENT_ID =" + CategoryId);
if (ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
TreeNode child = new TreeNode();
child.Text = dr["Q_CATEGORY_NAME"].ToString().Trim();
child.Name = dr["Q_CATEGORY_ID"].ToString().Trim();
//cmd is asigned to node tag
child.Tag = QuerysMenuCmd.CategorySelect;
child.Collapse();
//GET ALL QUERYS
DataContext MyDataContext = new DataContext(GConnectionString);
DataTable MyDataTable = new DataTable();
MyDataTable = MyDataContext.GetCategoryQuery(dr["Q_CATEGORY_ID"]);
foreach (DataRow Item in MyDataTable.Rows)
{
TreeNode MyNode = new TreeNode();
MyNode.Name = Item["QUERY_ID"].ToString();
MyNode.Text = Item["QUERY_NAME"].ToString();
//cmd is asigned to node tag
MyNode.Tag = QuerysMenuCmd.OpenQuery;
MyNode.StateImageIndex = 1;
child.Nodes.Add(MyNode);
}
parent.Nodes.Add(child);
FillChild(child, dr["Q_CATEGORY_ID"].ToString());
}
return 0;
}
else
{
return 0;
}
}
private TreeNode GetNode(string MyName, TreeNodeCollection parentCollection)
{
TreeNode ret = null;
TreeNode child = default(TreeNode);
//step through the parentcollection
foreach ( child in parentCollection) {
if (child.Name == MyName) {
ret = child;
// if there is child items then call this function recursively
} else if (child.GetNodeCount(false) > 0) {
ret = GetNode(MyName, child.Nodes);
}
if ((ret != null))
break; // TODO: might not be correct. Was : Exit For
//if something was found, exit out of the for loop
}
return ret;
}