Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Developing OutlookBar user control in ASP.NET

0.00/5 (No votes)
21 Nov 2004 1  
OutlookBar User Control in ASP.NET.

Sample Image - OutlookBar.jpg

Introduction

Many of you might have seen Outlookbar as shown above while using Microsoft Outlook application. This UI control has always fancied me. I felt why not use the power of ASP.NET to develop this control? All the OutlookBar menu and submenu items are configured from an XML file. So you can configure the XML file as per your requirement to display main menu and submenu items. Sample XML files used in demo project are for illustration purpose only. This article will walk you through the implementation of this as a user control in ASP.NET.

Background

Recently, I was working on master/detail DataGrid with collapsible feature. As most of you might be aware, TemplateColumn feature of DataGrid enables us to make use of templates such as Itemtemplate, EditTemplate, HeaderTemplate, FooterTemplate and SeparatorTemplate. These templates give developer control over what s/he wants to paint in each of these templates. Also, DataGrid provides OnEditCommand and OnCancelCommand events for which we can write handler code so that DataGrid can paint what is specified in Itemtemplate or EditItemTemplate. I have used the same concept for this control.

I have used asp:Button control in ItemTemplate section, and used asp:Button and other user controls using Repeater to display child items in EditTemplate section. I have wired the OnEditCommand event handler to asp:Button control. The code section below explains step by step implementation details.

Using the code

Outlookbar user control is implemented in Outlookbar.ascx. It has the following HTML declaration:

<%@ Register TagPrefix="uc1" TagName="ImageHandler" Src="ImageHandler.ascx" %>
<asp:DataGrid ShowHeader="False"  runat="server" OnEditCommand="OnEdit">

<Columns>
<asp:TemplateColumn>
<ItemTemplate>
<asp:Button Width="100%" BackColor="#cccc99" 
  Text='<%# DataBinder.Eval(Container.DataItem,"Caption") %>' 
  runat="server" CommandName="Edit" ID="Button1"/>
</ItemTemplate>
<EditItemTemplate>
<asp:Button width="100%" BackColor="#cccc99" 
  Text='<%# DataBinder.Eval(Container.DataItem,"Caption") %>' 
  runat="server" CommandName="Cancel" ID="Button2"/>
<uc1:ImageHandler id="imgHandle1" 
  SelectedIndex='<%# DataBinder.Eval(Container.DataItem,"MenuItemIndex") %>' 
  runat="server">
</uc1:ImageHandler>
</EditItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>

If you look at the above HTML, you can see that I have used DataGrid control. Please note that I have set ShowHeader attribute to false as this control has no headers. In Itemtemplate section, I have declared asp:Button control and have set its width to 100%. I have also set commandname property to 'Edit' so it gets wired to OnEditCommand event handler. EditTemplate section has asp:Button and another user control which displays all submenu items. I will explain this user control later in this article. Please note that Text property of asp:Button is set to Caption item of Datasource bound to Datagrid. ImageHandler user control has SelectedIndex property which is set using menuItemIndex property of Datasource.

The code behind of this control has the following details:

namespace OutLookStyleBar
{
    using System;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Xml;
    using System.IO;

    /// <SUMMARY>

    ///        Summary description for OutlookStyleBar.

    /// </SUMMARY>

    public abstract class OutlookStyleBar : System.Web.UI.UserControl
    {
        protected System.Web.UI.WebControls.DataGrid dgOutLookStyleBar;
        private string m_sMenuItemsXML;
        private void Page_Load(object sender, System.EventArgs e)
        {
            if(!IsPostBack)
            {
                GetMenuItems();
                dgOutLookStyleBar.EditItemIndex=2;
                BindData();
            }
        
        }

If you look at the above code snippet, the code behind class OutlookStyleBar has been derived from System.Web.UI.UserControl, and has the following variables. The first variable is dgOutLookStyleBar and is of type DataGrid, and another is a string variable m_sMenuItemsXML. This string variable holds the XML of all the main menu items. This XML string is used to set DataSource property of DataGrid. This is saved in viewstate to avoid frequent trips to database on every postback.

If you look at Page_Load handler, it invokes GetMenuItems method which populates the m_sMenuItemsXML from OutlookItems.xml.

Since I want to show one row item as expanded, I have set EditItemIndex as 2. So that when the control loads for the first time, it will show third row as expanded. BindData method binds the XML string to DataGrid.

Please download source code from the link shown at the top of this article for detailed implementation of the above methods. Now, let us see the code in OnEdit event handler.

public void OnEdit(object source, 
       System.Web.UI.WebControls.DataGridCommandEventArgs e)
{
  dgOutLookStyleBar.EditItemIndex= e.Item.ItemIndex;
  BindData();
}

If you look at the above code, it is very simple. When user clicks on any of the menu item, the OnEditCommand is fired and the OnEdit event handler is invoked. This just sets EditItemIndex property to the row value selected by the user. This is passed in event argument of type DataGridCommandEventArgs. The property is e.Item.ItemIndex. After setting EditItemIndex, the next step is to invoke BindData method so that DataGrid will paint as per EditTemplate section for the row selected. Rest of the rows are painted as per what is specified in Itemtemplate section.

Now, let us see how the inner control is implemented.

This control is implemented in ImageHandler.ascx. I have named it so because it has used asp:ImageButton control to represent sub menu items and also for up and down scrolling. The HTML declaration is shown below:

<table cellSpacing="1" cellPadding="1" width="100%" bgColor="#808080" border="0">
<tr>
    <td align="right" height="15"><asp:imagebutton id="btnUp" 
             Runat="server" ImageUrl="Images/UpArrow.gif" Height="15px" 
             Width="30px"></asp:imagebutton></td>
</tr>
<tr>
    <td align="middle">
     <asp:repeater id="drImageList" runat="server" 
                  OnItemCommand="ImageSelect_Handler">
        <HeaderTemplate>
          <div style="WIDTH: 100%; BACKGROUND-COLOR: #808080">
        </HeaderTemplate>
        <ItemTemplate>
          <br />
        <span>
         <asp:ImageButton Width="40px" Height="40px" CommandName="Item" 
            BackColor="#cccc99" 
            ImageUrl='<%# DataBinder.Eval(Container.DataItem,"ImageURL") %>' 
            Runat="server" />
        </span>
        <br />
        <span style="COLOR: white">
          <%# DataBinder.Eval(Container.DataItem,"Caption") %>
        </span></br>
        </ItemTemplate>
        <FooterTemplate>
          <br />
          </div>
        </FooterTemplate>
    </asp:repeater> </td>
   </tr>
   <tr>
        <td align="right" height="15"><asp:imagebutton id="btnDown" 
        Runat="server" ImageUrl="Images/DownArrow.gif" Height="15px" 
        Width="30px"></asp:imagebutton></td>
   </tr>
</table>

In the above HTML code, I have declared table tag having three rows. In <td> tag of first row, I have used asp:ImageButton control to represent Up Arrow. Middle row <td> tag contains Repeater control, and last row <td> tag contains another asp:ImageButton control to represent Down Arrow. Up & Down Arrow button controls provide handler to handle scrolling of image items shown in Repeater control.

Repeater control as you know is very flexible and gives us control over what to paint. I have used <DIV> tag in its HeaderTemplate and asp:ImageButton control inside <span> tag. Another <span> tag is used to contain Caption of Image_Menu_Item. Lastly, the Footer Template contains the end </DIV> tag.

Now, let us go through the code behind of ImageHandler.ascx which is in ImageHandler.ascx.cs file:

namespace OutLookStyleBar
{
    using System;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.Xml;
    using System.IO;

    /// <SUMMARY>

    ///        Summary description for ImageHandler.

    /// </SUMMARY>

    public abstract class ImageHandler : System.Web.UI.UserControl
    {
        protected System.Web.UI.WebControls.Repeater drImageList;
        private string m_sImageItemsXML;
        protected System.Web.UI.WebControls.ImageButton btnUp;
        protected System.Web.UI.WebControls.ImageButton btnDown;
        private int m_iSelectedIndex;
        private const int MAX_REPEATER_ITEMS =3;
        private int m_iCurrentPos =1;
        private int m_iTotalItems =8;

        private void Page_Load(object sender, System.EventArgs e)
        {
            // Put user code to initialize the page here

            if(!IsPostBack)
            {
            
                m_iCurrentPos=1;
                ViewState["CurrentPos"]= m_iCurrentPos.ToString();
                GetNewItems();
                BindData();

            }
            else
            {
                if((string)ViewState["CurrentPos"] != null)
                {
                    m_iCurrentPos = 
                          Int32.Parse((string)ViewState["CurrentPos"]);
                    m_iTotalItems = 
                          Int32.Parse((string)ViewState["TotalItems"]);
                }
                else
                {
                    m_iCurrentPos=1;
                    m_iTotalItems=5;
                }
            }
            
        }

If you look at the above code snippet, I have declared class ImageHandler which is derived from System.Web.UI.UserControl and has following declarations:

protected System.Web.UI.WebControls.Repeater drImageList;

private string m_sImageItemsXML;

protected System.Web.UI.WebControls.ImageButton btnUp;

protected System.Web.UI.WebControls.ImageButton btnDown;

private int m_iSelectedIndex;

private const int MAX_REPEATER_ITEMS =3;

private int m_iCurrentPos =1;

private int m_iTotalItems =8;
  • drImageList is a variable of type Repeater and will contain all the submenu items represented as Images.
  • btnUp and btnDown are two variables of type ImageButton used to provide handlers for up and down scrolling of Repeater items.
  • m_iSelectIndex is variable of type int and is used to hold position of parent menu item, which in our case is DataGrid row of OutlookBar.ascx. This variable is important as it is used to retrieve submenu items from ImageItems.xml based on its value.
  • MAX_REPEATER_ITEMS is an integer constant used to define maximum items to be shown at any given point in Repeater.
  • m_iCurrentPos is integer variable used to store position of top item shown in Repeater. m_iTotalItems is used to store total number of submenu items. These two variable values control when to show or hide up and down arrow buttons.
  • m_sImageItemsXML is a variable of type string used to store XML string retrieved from ImageItms.xml.

Inside Page_Load event handler, we retrieve the submenu items by invoking GetNewItems method, and then invokes BindData method to bind the XML retrieved to Repeater. It also sets the m_icurrentPos as 1 to display the top list of images equal to MAX_REPEATER_ITEMS.

Please note that values of these variables are preserved in viewstate so that it can be tracked during post back when user wants to scroll up or down.

SelectedIndex is defined as public property which is used by parent control to set its value. Once set, it invokes GetNewItems and BindData methodd to refresh ImageList of Repeater. The code snippet is as shown below:

// Sets the Selected Index property and refreshes repeater list based on new value.

public int SelectedIndex
{
    set {
        m_iSelectedIndex=value; 
        GetNewItems();
        BindData();
    }
}

GetNewItems method is responsible for retrieving submenu items from XML file based on value of SelectedIndex property and value of m_iCurrentPos. It uses XPATH expression to retrieve appropriate items from XML. BindData method is pretty standard as it binds the XML string to Repeater. You can download the code from the link shown at top of this article and refer its details.

Conclusion

We saw how the power of ASP.NET, especially DataGrid and Repeater, can be used to develop rich user controls such as OutlookBar. The source code contains the test web form which contains OutlookBar user control. Please download and see the working demo. If you face any difficulties, please contact me at gokuldasc@yahoo.com. Good Luck !!!

My Other Articles

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here