NEWSLETTER
 Note: SlidingMenu v2.0 is NOT compatible with vs2005, please do not try to install SlidingMenu v2.0 with your vs2005 - it will not work.
With layered areas you can hold a lot more information on a lot less space - SlidingMenu slide through these layers!
  Menulab home >> SlidingMenu >> How to Code         ASP.NET Offsite Freelance Programmer  
 
The code on this page focus on understanding, not presentation, if you search for visual inspiration, go to the Examples Section. This page is intended to assist you learning how to program the SlidingMenu by discussing some code in more dept than you will otherwise find in the more appealing sections around the SlidingMenu corner of this website. This page is divided in two sections, an easy to follow section about how to add Groups manually and a rather advanced section about how to add Groups from a database with the extra spice of implementing a relational-key structure between the GroupHeader and the GroupCanvas by nested databinding (this section is not for the beginner of web databinding).

Adding Groups Manually

This example is able of running immediately if you copy the xml markup to a Web Form page (inside the FORM element) in VS.NET IDE, just press the clipboard button to move the code to your clipboard (and paste to your code editor).

XML markup

XML markup result

0.<wm:SlidingMenu id="smManual" runat="server">
1.     <SlidingMenuStyle SlideSmootheness="20" SlideDelay="5" Width="135" Height="500" BorderStyle="Solid" BorderColor="#f7f7f7" BorderWidth="5" />
2.     <GroupHeaderStyle Height="20" />
3.     <GroupCanvasStyle BackgroundColor="#FFCC99" />
4.     <AddManualGroup>
5.         <GroupHeaderStyle Height="25" BorderWidth="0" BackgroundImage="/images/backgrounds/background_menulab_bottom.gif" />
6.         <GroupCanvasStyle BackgroundImage="/images/backgrounds/background_menulab3.gif" />
7.         <GroupHeader><span style="COLOR:#012d9a;font-weight:bold;font-size:16">Header 1</span></GroupHeader>
8.         <GroupCanvas>
9.             <table height="100%" cellSpacing=0 cellPadding=0 border=0>
10.                 <tr>
11.                     <td align="center"><span style="COLOR:#012d9a;font-weight:bold;font-size:16">Canvas 1</span></td>
12.                 </tr>
13.             </table>
14.         </GroupCanvas>
15.     </AddManualGroup>
16.     <AddManualGroup>
17.         <GroupHeaderStyle BorderWidth="2" Height="30" BorderColor="#FF9933" BackgroundColor="#FFCC99" OpenThisGroupAtStartup="true" />
18.         <GroupCanvasStyle />
19.         <GroupHeader><h2>Header 2</h2></GroupHeader>
20.         <GroupCanvas>
21.             <table cellSpacing=20 cellPadding=0 align=center border=0>
22.                 <tr>
23.                     <td><img src="/images/SlidingMenu/sad.gif"></td>
24.                     <td><img src="/images/SlidingMenu/laugh.gif"></td>
25.                 </tr>
26.                 ...
27.             </table>
28.         </GroupCanvas>
29.     </AddManualGroup>
30.     <AddManualGroup>
31.         <GroupCanvasStyle BackgroundColor="" />
32.         <GroupHeader>Header 3</GroupHeader>
33.         <GroupCanvas>Canvas 3</GroupCanvas>
34.     </AddManualGroup>
35.</wm:SlidingMenu>
Header 1

Header 2

Header 3

XML markup discussion

At line 1 some generel properties are set for the SlidingMenu - the sliding speed is set so that the Groups will jump 20 pixels every 5 millisecond (the default is 10 pixels every 5 milliseconds, but that is a little slow for a high SlidingMenu like here), the width (135 pixels) and height (500 pixels) properties are set to get a heigh visual presentation and a border around the whole SlidingMenu is defined - type solid, gray in color and 5 pixels width.
At line 2 I set the default height of all GroupHeaders to 20 pixels, so that if a particular Group does not define the GroupHeader height itself, that GroupHeader will be 20 pixels height.
There are 3 Groups each defined by the <AddManualGroup> containers, the first Group is defined on line 4 through 15, you can open the first Group by pressing the "Header 1" on the SlidingMenu example.
On line 5 the first Group override the default height of the GroupHeader (set on line 2) and set it instead to 25 pixels, also the GroupHeader border is set to 0 to avoid the SlidingMenu default of a 1 pixel border around the GroupHeader and lastly, the GroupHeader are set to contain a background image.
At line 6 the same background image is set to fill out the GroupCanvas of the first Group.
Each <AddManualGroup> element must have a <GroupHeader> and a <GroupCanvas> element. The <GroupHeader> of the first Group starts on line 7.
Line 10 starts the <GroupCanvas> element of the first Group. Inside this GroupCanvas element, there is a table used to horisontally and vertically align the content of the GroupCanvas, to be able to center the content vertically it is necessary to ensure that the table fill out the GroupCanvas, this is done by setting the height attribute to 100% (as you can see on line 9).
At line 16 starts the second Group. On line 17, the default GroupHeader height (set at line 2) is again overriden this time to 30 pixels and also there is a border 2 pixels wide and a border color, however not a border style, since the SlidingMenu default is solid. Also the background color of the GroupHeader is set (the same color as the default GroupCanvas background set on line 3). The most interesting however is the OpenThisGroupAtStartup attribute, which is set to true thereby forcing this Group to open on page load (except in the case of postback if the SlidingMenuStyle.RememberOpenGroup is true).
At line 19 you can see that the text "Header 1" is marked as H2, but then you look at the example, the "Header 2" text is green, this is because the stylesheet used on this site defines any H2 as being green alike (on line 7 you can see that a span tag is used to inline define styles for the "Header 1" text).
The second Group does also demonstrate that you can put pictures on the GroupCanvas, however you can put any HTML and (nestable) WebControls in both the GroupHeader and the GroupCanvas.
The third Group starting on line 30 is close to default (the GroupCanvas background is set to transparent, SlidingMenu default however on line 3, the SlidingMenu default was overridden with respect to background) and without extra html layout.

Adding Groups from a Database

If you are not comfortable with how .Net databinding works in WebControls, you should read the Structures Documentation - SlidingMenu Databinding before reading this.
The following example includes not only the xml markup (html-view), but also C# code in the code behind-file. The example is using 2 tables from the Access Northwind database, the selects from these tables are also shown (you can of course use other databases than Access as long as you can connect through ADO.Net).

XML markup

Result (XML, C# & DB)

0.<wm:SlidingMenu id="smFood" runat="server">
1.     <SlidingMenuStyle Width="370" Height="420" BorderWidth="3" BorderColor="#8AB4EC" />
2.     <GroupHeaderStyle Height="25" BackgroundImage="/images/backgrounds/background_tube_blue_height20.gif" BorderWidth="0" BackgroundColor="#3135ce" />
3.     <GroupCanvasStyle BackgroundColor="#8AB4EC" ScrollbarFaceColor="#8AB4EC" />
4.     <DataBound>
5.         <HeaderTemplate>
6.             <asp:Label id=lblHeader Runat="server" ForeColor="#ce9c31"></asp:Label>
7.         </HeaderTemplate>
8.         <CanvasTemplate>
9.             <table height="100%" cellSpacing=0 cellPadding=0 align=center border=0 style="padding:7px">
10.                 <tr>
11.                     <td vAlign=center>
12.                         <asp:Label id=lblDescription Runat="server" Width="350" ForeColor="#ce9c31"></asp:Label>
13.                         <asp:DataGrid id=dgProduct Runat="server" Width="310" BorderWidth="0" ForeColor="#ffffff" HeaderStyle-ForeColor="#ffffff" HeaderStyle-BackColor="#8AB4EC" BackColor="#8AB4EC"></asp:DataGrid>
14.                     </td>
15.                 </tr>
16.             </table>
17.         </CanvasTemplate>
18.     </DataBound>
19.</wm:SlidingMenu>
  
Beverages
Condiments
Confections
Dairy Products
Grains/Cereals
Breads, crackers, pasta, and cereal
ProductNameUnitPrice
Gustaf's Knäckebröd21
Tunnbröd9
Singaporean Hokkien Fried Mee14
Filo Mix7
Gnocchi di nonna Alice38
Ravioli Angelo19.5
Wimmers gute Semmelknödel33.25
Meat/Poultry
Produce
Seafood
 

XML markup discussion

At line 4 is the container <DataBound>. This container is indicating there to place the databound Group's (since it is possible to add Group's manually both before and after the <DataBound> tag). The <DataBound> container allways have 2 elements, the <HeaderTemplate> (starting at line 5) and <CanvasTemplate> (starting at line 8), together these elements form a Group and they will be instantiated for each item in the data source, that is: there will be a Group for each item in the data source.
At line 13 there is a DataGrid inside the <CanvasTemplate>, therefore a DataGrid will be placed on the canvas of each Group in the SlidingMenu (here a DataGrid for each item, DataRow, in the DataSource, DataRowCollection), the DataGrid holds information of product names and unit prices within a certain category of products (see the result SlidingMenu above).

Data source

Data source discussion

Categories
Products
CategoryIDProductNameUnitPrice
1Chai18
1Chang19
2Aniseed Syrup10
2Chef Anton's Cajun Seasoning22
2Chef Anton's Gumbo Mix21.35
2Grandma's Boysenberry Spread25
7Uncle Bob's Organic Dried Pears30
2Northwoods Cranberry Sauce40
6Mishi Kobe Niku97
8Ikura31
4Queso Cabrales21
4Queso Manchego La Pastora38
8Konbu6
7Tofu23.25
2Genen Shouyu15.5
3Pavlova17.45
6Alice Mutton39
8Carnarvon Tigers62.5
3Teatime Chocolate Biscuits9.2
3Sir Rodney's Marmalade81
3Sir Rodney's Scones10
5Gustaf's Knäckebröd21
5Tunnbröd9
1Guaraná Fantástica4.5
3NuNuCa Nuß-Nougat-Creme14
3Gumbär Gummibärchen31.23
3Schoggi Schokolade43.9
7Rössle Sauerkraut45.6
6Thüringer Rostbratwurst123.79
8Nord-Ost Matjeshering25.89
4Gorgonzola Telino12.5
4Mascarpone Fabioli32
4Geitost2.5
1Sasquatch Ale14
1Steeleye Stout18
8Inlagd Sill19
8Gravad lax26
1Côte de Blaye263.5
1Chartreuse verte18
8Boston Crab Meat18.4
8Jack's New England Clam Chowder9.65
5Singaporean Hokkien Fried Mee14
1Ipoh Coffee46
2Gula Malacca19.45
8Røgede sild9.5
8Spegesild12
3Zaanse koeken9.5
3Chocolade12.75
3Maxilaku20
3Valkoinen suklaa16.25
7Manjimup Dried Apples53
5Filo Mix7
6Perth Pasties32.8
6Tourtière7.45
6Pâté chinois24
5Gnocchi di nonna Alice38
5Ravioli Angelo19.5
8Escargots de Bourgogne13.25
4Raclette Courdavault55
4Camembert Pierrot34
2Sirop d'érable28.5
3Tarte au sucre49.3
2Vegie-spread43.9
5Wimmers gute Semmelknödel33.25
2Louisiana Fiery Hot Pepper Sauce21.05
2Louisiana Hot Spiced Okra17
1Laughing Lumberjack Lager14
3Scottish Longbreads12.5
4Gudbrandsdalsost36
1Outback Lager15
4Fløtemysost21.5
4Mozzarella di Giovanni34.8
8Röd Kaviar15
7Longlife Tofu10
1Rhönbräu Klosterbier7.75
1Lakkalikööri18
2Original Frankfurter grüne Soße13
This use of the SlidingMenu is not explained, but is rather easy to make. Here I have two Group's added manually and a DataGrid in each GroupCanvas, one bound to the Categories table and one to the Products table of the Access Northwind database.

The selects shown to the left are used as the data source of the example SlidingMenu above. In the example SlidingMenu above a Group is formed on each DataRow in the Categories table and the CategoryName is displayed in the GroupHeader. In the Products table the DataRow's are related to the Category table through the CategoryID column, this structure is utilized in the example SlidingMenu to display all the products in the GroupCanvas belonging to the category displayed in the GroupHeader.

C# code

0....
1.using System.Data.OleDb;
2.
3.namespace MyNamespace
4.{
5.     public class MyWebFormPage : System.Web.UI.Page
6.     {
7.         protected Webmodelling.Controls.Menues.SlidingMenu smFood;
8.         private System.Data.OleDb.OleDbDataAdapter oleDA;
9.
10.         private void Page_Load(object sender, System.EventArgs e)
11.         {
12.             //delegating the GroupDataBound event using the SlidingMenuGroupEventHandler
13.             smFood.GroupDataBound += new Webmodelling.Controls.Menues.SlidingMenuGroupEventHandler(smFood_GroupDataBound);
14.
15.             //getting a physical file reference to the Access database, Northwind
16.             string appl_physical_path = Request.PhysicalApplicationPath;
17.             if (!appl_physical_path.EndsWith("\\")){appl_physical_path = appl_physical_path + "\\";} //old habit, sorry
18.             string physicalPath_Northwind = appl_physical_path + @"Data\Northwind.mdb";
19.
20.             //establishing a Connection object (here an OleDbConnection)
21.             string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + physicalPath_Northwind;
22.             string sqlCategories = "SELECT CategoryID, CategoryName, Description FROM Categories";
23.             OleDbConnection objConn = new OleDbConnection(strConn);
24.            
25.             //filling a (disconnected) DataTable from the data store
26.             OleDbCommand objComm = new OleDbCommand();
27.             objComm.Connection = objConn;
28.             objComm.CommandText = sqlCategories;
29.             oleDA = new OleDbDataAdapter();
30.             oleDA.SelectCommand = objComm;
31.             DataTable dtCategories = new DataTable();
32.             oleDA.SelectCommand.Connection.Open();
33.             oleDA.Fill(dtCategories); //fill the DataTable (at this moment, there need to be an open connection to the data store)
34.             oleDA.SelectCommand.Connection.Close();
35.
36.             //setting the DataSource of the SlidingMenu, smFood
37.             smFood.DataSource = dtCategories.Rows; //the Rows property of a DataTable is a DataRowCollection, a DataRowCollection implements IEnumerable
38.             smFood.DataBind();
39.         }
40.
41.         protected void smFood_GroupDataBound(object sender, Webmodelling.Controls.Menues.SlidingMenuGroupEventArgse)
42.         {
43.             DataRowCollection dataSource = (DataRowCollection)smFood.DataSource;
44.             //DataRowCollection dataSource = (DataRowCollection)((Webmodelling.Controls.Menues.DataBound)sender).DataSource;
45.             Label lblHeader = (Label)e.GroupHeader.FindControl("lblHeader");
46.             Label lblDescription = (Label)e.GroupCanvas.FindControl("lblDescription");
47.             DataGrid dgProduct = (DataGrid)e.GroupCanvas.FindControl("dgProduct");
48.            
49.             lblHeader.Text = (string)dataSource[e.GroupIndex]["CategoryName"];
50.             lblDescription.Text = (string)dataSource[e.GroupIndex]["Description"];
51.
52.             //the DataSource of the DataGrid can take a DataTable
53.             dgProduct.DataSource = Product((int)dataSource[e.GroupIndex]["CategoryID"]);
54.             dgProduct.DataBind();
55.
56.             if (e.GroupIndex % 2 != 0)
57.             {
58.                 lblHeader.ForeColor = System.Drawing.ColorTranslator.FromHtml("#3135ce");
59.                 lblDescription.ForeColor = System.Drawing.ColorTranslator.FromHtml("#3135ce");
60.                 e.GroupHeader.GroupHeaderStyles.BackgroundColor = "#ce9c31";
61.                 e.GroupHeader.GroupHeaderStyles.BackgroundImage = "/images/backgrounds/background_tube_braun_height20.jpg";
62.                 e.GroupCanvas.GroupCanvasStyles.BackgroundColor = "#ce9c31";
63.                 e.GroupCanvas.GroupCanvasStyles.ScrollbarFaceColor = "#ce9c31";
64.                 dgProduct.ForeColor = System.Drawing.ColorTranslator.FromHtml("#ffffff");
65.                 dgProduct.HeaderStyle.BackColor = System.Drawing.ColorTranslator.FromHtml("#ce9c31");
66.                 dgProduct.BackColor = System.Drawing.ColorTranslator.FromHtml("#ce9c31");
67.             }
68.
69.             if ((string)dataSource[e.GroupIndex]["CategoryName"] == "Grains/Cereals")
70.             {
71.                 e.GroupHeader.GroupHeaderStyles.OpenThisGroupAtStartup = true;
72.             }
73.         }
74.
75.         //returning those products that belongs to the current category
76.         private DataTable Product(int CategoryID)
77.         {
78.             DataTable dt = new DataTable();
79.             string sqlProducts = "SELECT ProductName, UnitPrice FROM Products WHERE CategoryID = " + CategoryID;
80.             oleDA.SelectCommand.CommandText = sqlProducts;
81.             oleDA.SelectCommand.Connection.Open();
82.             oleDA.Fill(dt);
83.             oleDA.SelectCommand.Connection.Close();
84.             return dt;
85.         }
86.     }
87.}

C# code discussion

For each item in the data source of the SlidingMenu, the SlidingMenu will fire an event - GroupDataBound - you must write an eventhandler for that event and you must also connect the eventhandler to the event. The eventhandler is here called smFoold_GroupDataBound and starts on line 41. To connect that eventhandler with the GroupDataBound event, it is necessary to instantiate a delegate, you can see the syntax and types involved on line 13 (or as described in the documentation you can choose to let Visual Studio write the necessary code to hook up the event by double click the GroupDataBound event in design-view (choose the SlidingMenu in question, view Properties and choose the Event fane)).
On line 38 the GroupDatabound event is actually fired on the data source through the method .DataBind(), however to do that, there must also be a data source to fire on, the data source is set through the .DataSource property on line 37. The DataSource property is of type IEnumerable and therefore the property must be initialised with an object implementing the IEnumerable interface. A lot of common types are implementing the IEnumerable eg. [OleDb | Sql]DataAdapter and the DataRowCollection - on line 37 I am using a DataRowCollection.
At line 43, I initialize a handle to the data source by directly asking the relevant SlidingMenu instance (an alternative way to obtain such a handle is shown on line 44, this syntax is for use if you do at design time not know for which SlidingMenu the eventhandler is currently executing).
On line 45 I am declaring a handle to a Label Control "lblHeader" instantiated by the SlidingMenu based on the xml code (xml markup line 6). The SlidingMenu have added this Label Control to the Controls collection of the GroupHeader object instantiated as part of the Group formed on the current item in the data source.
On line 49 the Text property of that particular Label Control in that Header object of that Group is assigned a value from the current item in the data source. To find the item (DataRow) within the data source (DataRowCollection) on which the eventhandler is currently called upon, you must use the GroupIndex property of the GroupEventArgs transfered as an argument to the eventhandler. Since the DataSource is a DataRowCollection, the code dataSource[e.GroupIndex] will return a DataRow.
On line 47 I declare a handle to a DataGrid allready instantiated within the GroupCanvas (see xml code line 13).
On line 53 I set the DataSource property of the DataGrid instance (the DataGrid DataSource property can take a DataTable). The DataTable is filled with the Products table (see the 2 Access tables) there the CategoryID is the CategoryID of the current item (DataRow) in the data source of the SlidingMenu, thereby showing a relational key structure (as it is in the Access tables) between the GroupHeader and the GroupCanvas.
Since the DataSource property of the DataGrid instance is initialized, it is safe to call DataBind() on the same instance, thus filling up the DataGrid instance (because of the internal workings of a DataGrid I do not need to write an eventhandler to fill the columns of the DataGrid with the data source of the DataGrid, but if I needed to handle the ItemDataBound event of the DataGrid, I just have to delegate the event before calling DataBind().
On line 56 I catch every second item in the data source and set some of the style properties of the Group's and of the Controls within these Group's different from the default defined in the xml code.
On line 69 to 72 I specify that the Group formed on that DataRow there the CategoryName column is "Grains/Cerials" (see the Categorys table of the 2 Access tables), this Group should open then the page is loaded.
Contact Menulab   |   Terms & Conditions   |   Privacy Policy   |   Sitemap   |   Copyright © Menulab 2003. All rights reserved.
Enterprise
Developer
Professional
Targeting private but professional persons or small companies, the cost is very low only $29. Buy Online

This license allow deployment on ONE website (like here on www.menulab.com).
Server
Freeware