Skip to main content

ListView with group headers

In previews Post I was Explained about  Easy Way Running Background Tasks in ASP.NET , How to download a file in ASP.Net , Detecting Mobile Devices In asp.net Using  51Degrees.mobi components  

Now I am in this post Explained How to Use Listview With Group Headers 
 
ListView with group headers
Let's say we want to implement a ListView with group headers, where each group is defined by a certain data column having the same value. In other words, each time the data column has a new value (proceeding from top to bottom), we want to have a special view that highlights that fact.

Introduction

The ListView control renders its ItemTemplate once for every item in its DataSource. As discussed in Grouping Data with the ListView Control, it is possible to insert a grouping template every N records. This flexibility allows for scenarios like displaying data in a multi-column table.

While the built-in grouping feature is certainly useful, when it comes to displaying data most people think of grouping to mean that records with similar attributes are lumped together. For instance, the Ticket Booking database contains information about an assortment of products, and each product has attributes likep PNR_NUMBER, NAME, MOBILE_NO, BOOKED_BY, BOARDING_POINT, FARE and so forth. While each NAME name is unique, many PNR_NO share the same Boarding point  and  BoardingPointTime. When someone says, "I want to group the PNR_NUMBER data," usually they mean they want to group it by one of these common attributes. The following screenshot shows the user interface people most people associate with the term grouping.

Capture.JPG

tripsheet
Unfortunately the ListView's grouping feature does not allow for this style of grouping. The good news is that with a few lines of code and markup we can construct such an interface. This article shows how to build a flexible grouping interface that allows the user to choose what data field to group the data by. Read on to learn more!

    string LastBoardingPoint =string.Empty ;
 public string  AddGroupingRowIfBoardingHasChanged()
    {
        string values = string.Empty;
        string  CurrentBoardingPoint  = Eval("BUS_BOARDING_POINT").ToString();
        string boardingPointTime = Eval("START_TIME").ToString();
        string Landmark = Eval("LAND_MARK").ToString();
        if( CurrentBoardingPoint.Length==0)
        {
          CurrentBoardingPoint = "Unknown";     
        }
        else
            if(!LastBoardingPoint.Equals(CurrentBoardingPoint))
            {
              LastBoardingPoint = CurrentBoardingPoint;
              values = String.Format("<tr class='groupheader'><td colspan='13'>Boarding Point : {0} - {1} ,{2}  </td></tr>", CurrentBoardingPoint, boardingPointTime, Landmark);
            }
            else
            {
              values= string.Empty;
            }
        return values;
    }

By adding the preceding databinding syntax we are instructing the ListView to call the AddGroupingRowIfBoardingHasChanged() each time it renders the ItemTemplate, that it will do once per record being bound to the ListView. The AddGroupingRowIfBoardingHasChanged() method, that we will create momentarily, will return either an empty string (in the case that the supplier name hasn't changed since the last product) or the HTML for a table row that announces the new BoardingPoint.

Next, create the AddGroupingRowIfBoardingHasChanged() method in the page's code-behind class. This method must return a string value and canont be marked Private (that is, it must be marked as Public or Protected). Keep in mind that this method is called once for every record being bound to the ListView. Add the following code:

<asp:ListView ID="lvDetails" runat="server" OnItemDataBound="lvDetails_ItemDataBound"
                        OnDataBound="lvDetails_DataBound">
                        <LayoutTemplate>
                            <table width="100%" border="1px" cellpadding="0" cellspacing="0" id="tripsheet">
                                <thead>
                                    <tr>
                                        <th>
                                            SNo
                                        </th>
                                        <th>
                                            Ticket No
                                        </th>
                                        <th>
                                            Seat No
                                        </th>
                                        <th>
                                            Passenger Name
                                        </th>
                                        <th>
                                            Contact
                                        </th>
                                        <th>
                                            Droping Point
                                        </th>
                                        <th>
                                            Fare(Rs.)
                                        </th>
                                        <th>
                                            Com.(Rs.)
                                        </th>
                                        <th>
                                            Balance(Rs.)
                                        </th>
                                        <th>
                                            Booked By
                                        </th>
                                        <th>
                                            Booking Type
                                        </th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr id="itemPlaceHolder" runat="server">
                                    </tr>
                                </tbody>
                                <tfoot>
                                    <tr>
                                        <td colspan="5">
                                            &nbsp;
                                        </td>
                                        <td>
                                            Totals
                                        </td>
                                        <td>
                                            Rs.<asp:Label ID="lblTotalSum" Font-Bold="true" runat="server"></asp:Label>
                                        </td>
                                        <td>
                                            Rs.<asp:Label ID="lblTotalComm" Font-Bold="true" runat="server"></asp:Label>
                                        </td>
                                        <td>
                                            Rs.<asp:Label ID="lblTotalBalance" Font-Bold="true" runat="server"></asp:Label>
                                        </td>
                                    </tr>
                                </tfoot>
                            </table>
                        </LayoutTemplate>
                        <ItemTemplate>
                            <%# AddGroupingRowIfBoardingHasChanged() %>
                            <tr>
                                <td>
                                    <%# Container.DataItemIndex+1 %>
                                </td>
                                <td>
                                    <%# Eval("PNR_NUMBER")%>
                                </td>
                                <td>
                                    <%# Eval("SEAT_NUMBER")%>
                                </td>
                                <td>
                                    <%# Eval("CUSTOMER_NAME")%>
                                </td>
                                <td>
                                    <%# Eval("CUSTOMER_CONTACT")%>
                                </td>
                                <td>
                                    <%# Eval("DROPING_POINT")%>
                                </td>
                                <td>
                                    <%# Eval("FARE")%>
                                </td>
                                <td>
                                    <%# Eval("COMMISSION")%>
                                </td>
                                <td>
                                    <%# Convert.ToInt32(Eval("FARE")) - Convert.ToInt32(Eval("COMMISSION"))%>
                                </td>
                                <td>
                                    <%# Eval("BOOKED_AT")%>
                                </td>
                                <td>
                                    <%# Eval("BOOKING_TYPE")%>
                                </td>
                            </tr>
                        </ItemTemplate>
                        <EmptyItemTemplate>
                            No Bookings are made for this Service
                        </EmptyItemTemplate>
                    </asp:ListView>

ListView Items DataBound
The following is for the DataBound ListView Items:

int totalfare, totalCommisionAmount, balanceAmount;
// Calculating Totals
protected void lvDetails_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
      
        ListViewDataItem dataItem = (ListViewDataItem)e.Item;
        if (e.Item.ItemType == ListViewItemType.DataItem)
        {
            DataRowView rowView = (DataRowView)dataItem.DataItem;
            totalfare = totalfare + Convert.ToInt32(rowView["FARE"]);
            totalCommisionAmount = totalCommisionAmount + Convert.ToInt32(rowView["COMMISSION"]);
            balanceAmount = balanceAmount + (Convert.ToInt32(rowView["FARE"]) - Convert.ToInt32(rowView["COMMISSION"])); 
        }
    }
// Binding Totals to Labels
    protected void lvDetails_DataBound(object sender, EventArgs e)
    { 
        Label lblTotal = (Label)lvDetails.FindControl("lblTotalSum");
        lblTotal.Text = totalfare.ToString();
        Label lblTotalCommisionAmount = (Label)lvDetails.FindControl("lblTotalComm");
        lblTotalCommisionAmount.Text = totalCommisionAmount.ToString();
        Label lblTotalBalanceAmount = (Label)lvDetails.FindControl("lblTotalBalance");
        lblTotalBalanceAmount.Text = balanceAmount.ToString();
    }

Grouping Method Based On PNR_NUMBER
The following is the grouping method based On PNR_NUMBER:

private DataTable GenerateData(DataTable dtDetails)
    {
        string currentpnr = string.Empty;
        //Geting Data Table structure
       // DtDetails Have the actual data
        DataTable newData = dtDetails.Clone();
        // Getting Distinct datatable PNR_NUMBERS
        DataTable dtDistinctData = dtDetails.DefaultView.ToTable("NeWData", true, "PNR_NUMBER");
        StringBuilder sbSeats = new StringBuilder();
        foreach (DataRow drow in dtDistinctData.Rows)
        {
            int fareSum = 0, commitionSum = 0;
            currentpnr = Convert.ToString(drow["PNR_NUMBER"]);
            //Selecting the rows
            DataRow[] rows = dtDetails.Select("PNR_NUMBER='" + currentpnr + "'");
            //Seats join
            var result = rows.Select(row => row[3].ToString()).ToArray();
            string joinseats = string.Join(",", result);
            //fares sum
            string[] resultfare = rows.Select(row => row[11].ToString()).ToArray();
            for (int i = 0; i < resultfare.Length; i++)
            {
                fareSum = fareSum + Convert.ToInt32(resultfare[i]);
            }
            //commition sum
            string[] resultcomm = rows.Select(row => row[16].ToString()).ToArray();
            for (int i = 0; i < resultcomm.Length; i++)
            {
                commitionSum = commitionSum + Convert.ToInt32(resultcomm[i]);
            }
            //gender join
            var resultgender = rows.Select(row => row[4].ToString()).ToArray();
            string joingenders = string.Join(",", resultgender);
            // copy data to new datatable
            DataRow drrow = newData.NewRow();
            drrow["PNR_NUMBER"] = currentpnr;
            drrow["SEAT_NUMBER"] = joinseats + "(" + joingenders + ")";
            drrow["FARE"] = fareSum;
            drrow["COMMISSION"] = commitionSum;
            drrow["CUSTOMER_GENDER"] = joingenders;
            drrow["CUSTOMER_NAME"] = rows[0]["CUSTOMER_NAME"];
            drrow["CUSTOMER_CONTACT"] = rows[0]["CUSTOMER_CONTACT"];
            drrow["BUS_BOARDING_POINT"] = rows[0]["BUS_BOARDING_POINT"];
            drrow["BOOKED_AT"] = rows[0]["BOOKED_AT"];
            drrow["DROPING_POINT"] = rows[0]["DROPING_POINT"];
            drrow["START_TIME"] = rows[0]["START_TIME"];
            drrow["BOOKING_TYPE"] = rows[0]["BOOKING_TYPE"];
            drrow["LAND_MARK"] = rows[0]["LAND_MARK"];
            //Adding Rows to table
            newData.Rows.Add(drrow);
        }

        return newData;
    }

  protected void GetPassengersDetails()
    {
       // getting individual total booked seats from service
            DataTable dtPassengers = objBusiness.GetData(EBEnum.Enum.Functionality.Bookings.ToString(), 0,  ref strProcedure);
           DataTable newdata = this.GenerateData(dtPassengers);
           lvDetails.DataSource = newdata;
           lvDetails.DataBind();
     }
       
That's all there is to it! With this code in place we now get the desired grouping interface.

Comments

Popular posts from this blog

Asp.Net AjaxFileUpload Control With Drag Drop And Progress Bar

This Example explains how to use AjaxFileUpload Control With Drag Drop And Progress Bar Functionality In Asp.Net 2.0 3.5 4.0 C# And VB.NET. Previous Post  I was Explained about the   jQuery - Allow Alphanumeric (Alphabets & Numbers) Characters in Textbox using JavaScript  ,  Fileupload show selected file in label when file selected  ,  Check for file size with JavaScript before uploading  . May 2012 release of AjaxControlToolkit includes a new AjaxFileUpload Control  which supports Multiple File Upload, Progress Bar and Drag And Drop functionality. These new features are supported by Google Chrome version 16+, Firefox 8+ , Safari 5+ and Internet explorer 10 + , IE9 or earlier does not support this feature. To start with it, download and put latest AjaxControlToolkit.dll in Bin folder of application, Place ToolkitScriptManager  and AjaxFileUpload on the page. HTML SOURCE < asp:ToolkitScriptManager I...

View online files using the Google Docs Viewer

Use Google Docs Viewer for Document viewing within Browser I was looking for a way to let users see Microsoft Word Doc or PDF files online while using my application without leaving their browser without downloading files and then opening it to view with Word or PDF viewer . I was looking for some way out either via any PHP or Microsoft.NET libraries, did some googling on that; but later on I just got an idea that google already has all code written for me.. when I have any email attachment in PDF or DOC or DOCX google does it for me ..! Even while searching I can see PDFs by converting them in HTML. So I just googled it up and found that Google already has this ability that we can use Google Docs Viewer without any Google Account Login . YES that's true no Google Account login is required. It's damn simple and easy. Just pass document path as attachment as parameter and we are done. Google Docs Viewer gives us ability to embed PDF, DOC/DOCX, PPT, TIFF:...

How to send mail asynchronously in asp.net with MailMessage

With Microsoft.NET Framework 2.0 everything is asynchronous and we can send mail also asynchronously. This features is very useful when you send lots of bulk mails like offers , Discounts , Greetings . You don’t have to wait for response from mail server and you can do other task . By using     SmtpClient . SendAsync Method (MailMessage, Object)    you need to do  System.Net.Mail has also added asynchronous support for sending email. To send asynchronously, you need need to Wire up a SendCompleted event Create the SendCompleted event Call SmtpClient.SendAsync smtpClient.send() will initiate the sending on the main/ui  thread and would block.  smtpClient.SendAsync() will pick a thread from the .NET Thread Pool and execute the method on that thread. So your main UI will not hang or block . Let's create a simple example to send mail. For sending mail asynchronously you need to create a event handler that will notify that mail success...