First of all, a huge thanks for giving a good response to my first article on CodeProject. In this article, I would illustrate the use of bit operations on integers to help us make a cool customizable menu. As always, my motto is minimum programming effort.
You need to have a good understanding of the .NET CLR to better understand this article, as the concept relies heavily on it.
Let me first of all brief you on the use of the bitwise
'&' operator. This operator is used to check the status of bits in integer values. Note the following about
- 0 & 1 = 0
- 1 & 0 = 0
- 0 & 0 = 0
- 1 & 1 = 1
I would not go into the details of converting an integer to bits. But just note the following property:
10111011 & 00100000 = 00100000
I.e., 187 & 32 = 32
Using the Code
We would need to add SQL CLR to our code, as applying '&' to an integer is illegal in C#. We do this by using the
Microsoft.SqlServer.Server namespace. For building up this menu, we assign a score in the form of 2^n to each item as:
<MenuItem Title="A" URL="Page1.aspx" Value="1">
<MenuItem Title="A.1" URL="Page1-1.aspx" Value="2" />
<MenuItem Title="A.2" URL="Page1-2.aspx" Value="4" />
<MenuItem Title="B" URL="Page2.aspx" Value="8">
<MenuItem Title="B.1" URL="Page2-1.aspx" Value="16"/>
<MenuItem Title="B.2" URL="Page2-2.aspx" Value="32"/>
<MenuItem Title="C" URL="Page3.aspx" Value="64">
<MenuItem Title="C.1" URL="Page3-1.aspx" Value="128"/>
<MenuItem Title="C.2" URL="Page3-2.aspx" Value="256">
<MenuItem Title="C.2.1" URL="Page3-2-1.aspx" Value="512"/>
<MenuItem Title="C.2.2" URL="Page3-2-2.aspx" Value="1024">
<MenuItem Title="C.2.2.1" URL="Page3-2-2.aspx" Value="2048"/>
We also assign a score to each user that is calculated as the sum of all the values of menu items that we want the user to see. Say, we want a user to only see the Main menu A with all the subitems, then the score will be 1+2+4 = 7. Note that you need to add up the main menu score, i.e., the score of A, B, or C if you want to use any of its child menus.
Now, let's jump to the last critical part, that is the CLR code that performs the '&' operation with the menu's values to see whether a user is eligible to see the navigation link or not.
private bool Addable(int score, int valueToCheck)
return ((score & valueToCheck) == valueToCheck);
Now, all we need is a record of score of each user and get the required XML data source to bind to a menu or tree. Each menu item's value is checked for its '&' ability with the total score, to see if it fits the user's menu criteria.
if (score != 0)
datasetReadXML = new DataSet();
datasetMenuItems = new DataSet();
xdsMenuData = new XmlDataSource();
xdsMenuData.EnableCaching = false;
xdsMenuData.EnableViewState = false;
datasetMenuItems = datasetReadXML.Clone();
foreach (DataRow drWorker in datasetReadXML.Tables.Rows)
if (Addable(score, Convert.ToInt32(drWorker["Value"])))
stringWriter = new System.IO.StringWriter();
xdsMenuData.Data = stringWriter.ToString();
TreeMenu.DataSource = xdsMenuData;
Menu.DataSource = xdsMenuData;
I have used XML to keep track of user scores. However, you may use your own choice of database to do the same. All you need is a score. The attached code is self explanatory.
Points of Interest
Please remember to set the
EnableViewState properties of the XML data source to
false for getting the updated values. I have seen a lot of people on various forums going nuts over it.