Welcome Guest Search | Active Topics | Sign In | Register

Menu - using DB/XMLDataSource - wanting custom image headers Options
Posted: Wednesday, August 8, 2007 2:03:12 PM
Rank: Member
Groups: Member

Joined: 8/8/2007
Posts: 23
See Below:
Here is what I'm wanting, but doing it dynamically...

Ok, I'd like to dynamically populate the menu using a DB.
I've done this with the asp:Menu rather simply by populating a DataSet (by a DB), adding a relation and then setting an XMLDataSource.Data = to the Dataset's.GetXml property. Now the XMLDataSource
is in the .aspx page, which is bound to the asp:Menu control, and has a TransformFile applied to it that takes the xml from my call to the DB and creates some XML that the menu control can read. See Below:

Code: Visual Basic.NET
Dim ds As New DataSet("Menus")
Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("menuDB").ToString)
   Dim sql As String = "Select MenuID, ParentID, Text, Description, URL from Menu"
   Dim da As New SqlDataAdapter(sql, conn)
   da.Fill(ds)
End Using

ds.Tables(0).TableName = "Menu"
Dim relation As New DataRelation("ParentChild", ds.Tables("Menu").Columns("MenuID"), ds.Tables("Menu").Columns("ParentID"), True)
relation.Nested = True
ds.Relations.Add(relation)

xmlDataSource.Data = ds.GetXml()


I say the above because what I'd like to do, I think I have to do some of the above (use a xslt) sheet. To be able to create menu's with images, as in this example, I'm thinking that i'll need to set some kind of flag in my DB. Is this correct, am I asking the right question? :)
Posted: Wednesday, August 8, 2007 2:07:10 PM
Rank: Member
Groups: Member

Joined: 8/8/2007
Posts: 23
As a follow up, the myExecution and myPeople are images. How do I create the same menu (as in the above link) by setting the ImageURL in the DB? I hope I'm not confusing you. My goal is to make your menu completely dynamic, i.e. setting an ImageURL in my Menu DB, and then, I'm thinking, using an .xslt to create XML that you menu can use...
eo_support
Posted: Wednesday, August 8, 2007 2:34:16 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,082
Hi Wade,

Thanks for posting your question here. The sample menu that we created for you is one level, even though it looks like two sections, but that's only because there are two special menu items.

The reason of knowing the levels is important is because data binding works on "levels", parent and child relationship is not necessary for one level menus, but is a must for multiple level menus. So if you have a parent child relationship like this in your DB:

My execution -> restaurant data, accounting home, ....
My people -> HR home, my forums, ....

When you populate from the DB, you will get restaurant data, accouting home... as popup sub menu items of "my execution", much the way like "Products" and "Product 1" in this sample:

http://www.essentialobjects.com/Demo/Default.aspx?path=Menu\_i0\_i8

This is different than ASP.NET Menu, where you have a "static level" property that you can set to a number greater than one to display sub menu items statically.

In order to populate them into the same level, all the data in your data source must be on the same level: Records in the same table, child nodes on the same parent nodes in XML file, etc. If your contents in your database is hierarchical, you will need to write some code to "flat" them. One way to do this is to add them all into an ArrayList:

Code: C#
ArrayList items = new ArrayList();

//Put all rows in the first table into items
items.AddRange(ds.Tables[0].Rows);   

//Put all rows in the second table into items
items.AddRange(ds.Tables[1].Rows);


The above code is only for showing you how to put contents of multiple tables into one ArrayList. In reality you may only want to put some rows into it. Of course if the whole purpose of your DB is to create the menu items then you can also change your DB structure from multiple parent-child tables into one table.

Once you have such a "flat" data source, you can bind it to our menu:

Code: C#
Menu1.DataSource = items;
Menu1.DataBind();


In this case, because the data source is an array list, the menu actually doesn't know what to do with each item in the array list. To solve this problem, you would handle the menu's ItemDataBound event. Our menu calls this event handler after it creates every menu item from the data source. So inside that handler you can do:

Code: C#
//Get the current data item 
DataRowView row = (DataRowView)Menu1.DataItem;

//Modify the current menu item based on the data item
if (row["some_field"] == "some_value")
  e.MenuItem.Image.Url = "some_url";


Note the code above is just for demonstration purpose and the if statement actually does not compile. So you will need to modify that.

When you put all those together, you would have a db-driven menu.

Thanks

Posted: Wednesday, August 8, 2007 3:08:27 PM
Rank: Member
Groups: Member

Joined: 8/8/2007
Posts: 23
Wow, you guys are quick...
Okay, so what if I actually don't set any hierarchy in my DB. That's easy enough to change. How would I then tell your menu that a particular menu item is actually an image?
eo_support
Posted: Wednesday, August 8, 2007 3:27:50 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,082
Hi Wade,

Actually you don't. In this particular case the menu doesn't know those two items are images. The difference between these two items and all other items are the item text. While all other items have "straight" text, these two have a bit html code. So your menu table could be something like this:

item_id, item_text
1, <img style="position:relative;left:-2px;top:12px" src="some_image.gif" />
2, RESTAURANT DATA
3, ACCOUNTING DATA
.....

The menu doesn't make a distinguish between item 1 and item 2. It just take whatever text (actually treated as HTML) you give to it and place them inside each menu item. So all you need to do is to feed different menu items different text.

One menu item (my people) does have a different background image (you may have noticed two item background images in images foloder), for that you may still want to use ItemDataBound event. It's much easier to take care of those special logic by code rather than by data.

Thanks

Wade wrote:
How would I then tell your menu that a particular menu item is actually an image?


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.