Friday, September 16, 2011

Enhanced List Box Control


Introduction

An article about the basics of Listbox control and the operations that can be done using simplified code.

Background

MSDN Library Web Server Controls

Using the code

About ListBox Control

The controls that are used to List the data in Asp.Net are :
  1. CheckBoxList
  2. DropDownList
  3. ListBox
  4. RadioButtonList
We are about to concentrate on ListBox Control.

The Namespace Hierarchy

System.Object
      System.Web.UI.Control
            System.Web.UI.WebControls.WebControl
                  System.Web.UI.WebControls.ListControl 

Important Properties and Methods

About ListBox class

Properties:
DataSourceA data source that provides data for populating the list control.
DataMemberA string that specifies a particular table in the DataSource.
DataTextFieldA data that specifies the field of the data source that provides the text content of the listitems.
DataValueFieldA data that specifies the field of the data source that provides the value of each list item.
SelectionModeThe ListSelectionMode enumeration represents the selection mode of the ListBox control that determines whether a user can select multiple items or just a single item.
SelectedItemIt represents the selected item with the lowest index in the list control.
SelectedIndexIt represents the lowest ordinal index of the selected items in the list.
SelectedValueIt represents the value of the selected item in the list control.

About ListItemCollection Class

The ListItemCollection class represents a collection of ListItem objects. The ListItem objects represent the items displayed in list controls.
Properties :
ListItemCollection.CountIt gets the number of ListItem objects in the collection.
ListItemCollection.ItemIt Gets a ListItem at the specified index in the collection.
Methods:
  1. Add
  2. AddRange
  3. Remove
  4. RemoveAt
  5. Clear
  6. Insert

About ListItem Class

ListItem control represents an individual data item within a data-bound list control
Eg., <asp:ListItem Value="1" Text="Item 1">Sample Item 1</asp:ListItem>
Properties :
ListItem.SelectedIt Gets or sets a value indicating whether the item is selected.
ListItem.TextThe text displayed in a list control for the item represented by the Listitem.
ListItem.ValueThe value associated in a list control for the item represented by the ListItem.

Functions

The AddRemoveAll function inserts all items from the Source Listbox to the Target Listbox and removes all items in the Source Listbox. It is a generalised function and you can specify the source and target Listbox according to your need.
private void AddRemoveAll(ListBox aSource, ListBox aTarget)
 {
  try
  {
   foreach(ListItem item in aSource.Items)
   aTarget.Items.Add(item);
   aSource.Items.Clear();
  }
  catch(Exception expException)
  {
    Response.Write(expException.Message);
  }
 }

The AddRemoveItem function inserts the selected item from the Source Listbox to the Target Listbox and removes the item in the Source Listbox. It is also a generalised function and you can specify the source and target Listboxaccording to your need.
private void AddRemoveItem(ListBox aSource, ListBox aTarget)
 {
  ListItemCollection licCollection;
  try
  {
     licCollection = new ListItemCollection();
  for(int intCount=0;intCount < aSource.Items.Count;intCount++)
     {
        if(aSource.Items[intCount].Selected==true)
     licCollection.Add(aSource.Items[intCount]); 
   }
   for(int intCount=0;intCount < licCollection.Count;intCount++)
   {
        aSource.Items.Remove(licCollection[intCount]);
     aTarget.Items.Add(licCollection[intCount]);
   }
  }
  catch(Exception expException)
  {
     Response.Write(expException.Message);
  }
  finally
  {
     licCollection = null;
  }
 }
The MoveUp function moves the selected item to a position above. When you want to store the items from theListBox by rearranging the selected items you can just loop the items and save it. The data of the selected item. Then it removes the selected item from its current position and inserts it a position above. The loop goes only till the selected item so the other items will not be looped. Hence improving the performance.
private void private void MoveUp(ListBox lstBox)
 { 
  int   iIndex, iCount, iOffset, iInsertAt,iIndexSelectedMarker = -1;
  string lItemData,lItemval;

  try
   {
  // Get the count of items in the list control

  iCount = lstBox.Items.Count;
       
  // Set the base loop index and the increment/decrement value based

  // on the direction the item are being moved (up or down).

  iIndex = 0;
  iOffset = -1;
  // Loop through all of the items in the list.

  while(iIndex < iCount) 
   {
    // Check if this item is selected.

    if(lstBox.SelectedIndex > 0)
    {
    // Get the item data for this item

     lItemval =lstBox.SelectedItem.Value.ToString();
    lItemData = lstBox.SelectedItem.Text.ToString() ;
    iIndexSelectedMarker=lstBox.SelectedIndex; 
      
    // Don't move selected items past other selected items

       if(-1 != iIndexSelectedMarker)
       {
         for(int iIndex2 = 0; iIndex2 < iCount; ++iIndex2)
      {
        // Find the index of this item in enabled list

            if(lItemval == lstBox.Items[iIndex2].Value.ToString())
         {
           
          // Remove the item from its current position

             lstBox.Items.RemoveAt(iIndex2);  
             
      // Reinsert the item in the array one space higher 

             // than its previous position

             iInsertAt=(iIndex2 + iOffset)<0?0:iIndex2+iOffset;
             ListItem li= new ListItem(lItemData,lItemval);
          lstBox.Items.Insert(iInsertAt,li);
          break;
         }
        }
        }
     }
            
     // If this item wasn't selected save the index so we can check

        // it later so we don't move past the any selected items.

        else if(-1 == iIndexSelectedMarker)
        {
         iIndexSelectedMarker = iIndex;  
       break;
     }
      iIndex = iIndex + 1;
    }
    if(iIndexSelectedMarker==0)
      lstBox.SelectedIndex=iIndexSelectedMarker;
    else
      lstBox.SelectedIndex=iIndexSelectedMarker-1;
   }
   catch(Exception expException)
   {
    Response.Write(expException.Message); 
   } 
 } 
The MoveDown function moves the selected item to a position below. The data of the selected item. Then it removes the selected item from its current position and inserts it a position below.
private void MoveDown(ListBox lstBox)
 {
   try
    {
      int   iIndex, iCount, iOffset, InsertAt,iIndexSelectedMarker = -1;
    string  lItemData;
     string  lItemval;
          
    // Get the count of items in the list control

    iCount = lstBox.Items.Count;
        
    // Set the base loop index and the increment/decrement value based on 

    // the direction the item are being moved (up or down).

    iIndex = iCount - 1;
    iOffset = 1;
          
    // Loop through all of the items in the list.

    while(iIndex >= 0) 
     {
          
    // Check if this item is selected.

    if(lstBox.SelectedIndex >= 0)
      {
            
        // Get the item data for this item

        lItemData = lstBox.SelectedItem.Text.ToString();
        lItemval =lstBox.SelectedItem.Value.ToString();
        iIndexSelectedMarker=lstBox.SelectedIndex; 
            
        // Don't move selected items past other selected items

           if(-1 != iIndexSelectedMarker)
           {
              for(int iIndex2 = 0; iIndex2 < iCount-1; ++iIndex2)
            {
              // Find the index of this item in enabled list

              if( lItemval == lstBox.Items[iIndex2].Value.ToString())
           {
                  // Remove the item from its current position

               lstBox.Items.RemoveAt(iIndex2);
                  // Reinsert the item in the array one space lower 

             // than its previous position

                  iInsertAt=(iIndex2+iOffset) < 0?0:iIndex2+iOffset;
                  ListItem li = new ListItem(lItemData,lItemval);
               lstBox.Items.Insert(iInsertAt,li);
                  break;
               }
           }
            }
        }
       iIndex = iIndex - 1;
      }
      if(iIndexSelectedMarker==lstBox.Items.Count-1)
        lstBox.SelectedIndex=iIndexSelectedMarker;
      else
      lstBox.SelectedIndex=iIndexSelectedMarker+1;
   }
   catch(Exception expException)
     {
      Response.Write(expException.Message);
     }
 }
  
  

Points Of Interest

The Article can be extended with databinding features. The Databinding can be done from the Database with theDatasourceDataTextField and Datavaluefield properties set. For simplification for beginners I have added the items in design time.



19.1 How to make the listbox scroll down to show it's last entry when the page loads?




<p> 
<asp:ListBox id="ListBox1" runat="server"></asp:ListBox> 
</p> 
<p> 
<asp:Button id="buttonAdd" runat="server" Text="Add"></asp:Button> 
</p> 


In button Click Event
VB.NET

ListBox1.Items.Add(DateTime.Now.ToString("MMM dd, yyyy") + " " + DateTime.Now.ToString("t")) 
Dim scrollScript As String 
scrollScript &= "<script language='javascript'>" 
scrollScript &= "document.forms[0].ListBox1.selectedIndex " & _ 
" = document.forms[0].ListBox1.options.length-1;" 
scrollScript &= "<" & "/" & "script>" 
Page.RegisterStartupScript("", scrollScript) 


C#

ListBox1.Items.Add(DateTime.Now.ToString("MMM dd, yyyy") + " " + DateTime.Now.ToString("t")); 
string scrollScript="" ; 
scrollScript += "<script language='javascript'>"; 
scrollScript += "document.forms[0].ListBox1.selectedIndex = document.forms[0].ListBox1.options.length-1;";
scrollScript += "<" + "/" + "script>"; 
Page.RegisterStartupScript("", scrollScript); 



19.2 How to check if an item already exists in a listbox?



VB.NET

Dim lstitem As ListItem = ListBox1.Items.FindByValue("<valuecheckedfor>") 
If Not lstitem Is Nothing Then 
Response.Write("Item Exists") 
Else 
Response.Write("Item Does not exist") 
End If 


C#

ListItem lstitem = ListBox1.Items.FindByValue("<valuecheckedfor>"); 
if ( lstitem !=null) 
     Response.Write ("Does exist"); 
else 
     Response.Write ("Does not exist"); 


You can also use FindByText instead of FindByValue.

19.3 How to populate a listbox with the Column Names in a Table?



VB.NET

'Populate the dataset 
Dim dc As DataColumn 
For Each dc In ds.Tables(0).Columns 
     ListBox1.Items.Add(dc.ColumnName) 
Next 


C#

//Populate the Dataset 
foreach (DataColumn dc in ds.Tables[0].Columns) 
     ListBox1.Items.Add(dc.ColumnName); 



19.4 How to add items dynamically to a ListBox using an ArrayList?




<asp:ListBox id="ListBox1" runat="server" AutoPostBack="True"></asp:ListBox> 


VB.NET

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     'Put user code to initialize the page here 
     If Not IsPostBack Then 
          Dim arrList As New ArrayList 
          arrList.Add("One") 
          arrList.Add("Two") 
          arrList.Add("Three") 
          arrList.Add("Four") 
          ListBox1.DataSource = arrList 
          ListBox1.DataBind() 
     End If 
End Sub 

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged 
     Response.Write(ListBox1.SelectedItem.Text) 
End Sub 


C#

private void Page_Load(object sender, System.EventArgs e) 
     // Put user code to initialize the page here 
     if (!Page.IsPostBack ) 
     { 
          ArrayList arrList = new ArrayList(); 
          arrList.Add("One"); 
          arrList.Add("Two"); 
          arrList.Add("Three"); 
          arrList.Add("Four"); 
          ListBox1.DataSource = arrList; 
          ListBox1.DataBind(); 
     } 

private void ListBox1_SelectedIndexChanged(object sender, System.EventArgs e) 
     Response.Write (ListBox1.SelectedItem.Text ); 



19.5 How to move items between ListBoxes?




<asp:ListBox id="ListBox1" runat="server"> 
     <asp:ListItem Value="Faqs">Faqs</asp:ListItem> 
     <asp:ListItem Value="Tips">Tips</asp:ListItem> 
     <asp:ListItem Value="Tricks">Tricks</asp:ListItem> 
     <asp:ListItem Value="Advanced">Advanced</asp:ListItem> 
</asp:ListBox> 
<asp:Button id="btnToRight" style="Z-INDEX: 101; LEFT: 112px; POSITION: absolute; TOP: 24px" 
     runat="server" Text=">"></asp:Button> 
<asp:ListBox id="ListBox2" style="Z-INDEX: 102; LEFT: 152px; POSITION: absolute; TOP: 16px" runat="server"></asp:ListBox> 
<asp:RequiredFieldValidator id="RequiredFieldValidator1" style="Z-INDEX: 103; LEFT: 24px; POSITION: absolute; TOP: 120px" 
     runat="server" ErrorMessage="Please Select Item" ControlToValidate="ListBox1"></asp:RequiredFieldValidator> 


VB.NET

Private Sub btnToRight_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnToRight.Click 
     If ListBox1.Items.Count = 0 Then 
          Response.Write("No item to move") 
     End If 
     Dim itemremoved As String = ListBox1.SelectedItem.Text 
     ListBox1.Items.Remove(itemremoved) 
     ListBox2.Items.Add(itemremoved) 
End Sub 


C#

private void btnToRight_Click(object sender, System.EventArgs e) 
     if (ListBox1.Items.Count == 0 ) 
     { 
          Response.Write("No item to move"); 
     } 
string itemremoved = ListBox1.SelectedItem.Text; 
ListBox1.Items.Remove(itemremoved); 
ListBox2.Items.Add(itemremoved); 



19.6 How to select a specific Item in a ListBox in code?



VB.NET

ListBox1.Items.FindByValue(<Value>).Selected = true 
'ListBox1.Items.FindByText(<Text>).Selected = true 


C#

ListBox1.Items.FindByValue(<Value>).Selected = true; 
//ListBox1.Items.FindByText(<Text>).Selected = true; 



19.7 How can you use a ListBox control to display items with Price above a specific value in one color and the ones below that value in a different color?



The ListBox Web server control prevents us from assigning the style property to each item in the ListBox. This bug is confirmed by Microsoft Knowledge Base Article - 309338 
So, instead use a HTML ListBox with runat=server

<SELECT id="listbox1" size="14" runat="server" > 
</SELECT> 


VB.NET

Dim myconnection As SqlConnection 
Dim myda As SqlDataAdapter 
Dim ds As DataSet 
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     myconnection = New SqlConnection("Server=localhost;uid=sa;password=;database=northwind;") 
     myda = New SqlDataAdapter("Select * from Products ", myconnection) 
     ds = New DataSet() 
     myda.Fill(ds, "AllTables") 
     dim i as Integer 
     For i = 0 To ds.Tables(0).Rows.Count - 1 
          listBox1.Items.Add(New ListItem(ds.Tables(0).Rows(i)("UnitPrice"), ds.Tables(0).Rows(i)("ProductID"))) 
          If ds.Tables(0).Rows(i)("UnitPrice") <= 25 Then 
               listBox1.Items(i).Attributes.Add("style", "color:red") 
          Else 
               listBox1.Items(i).Attributes.Add("style", "color:green") 
          End If 
     Next 
End Sub 


C#

SqlConnection mycn; 
SqlDataAdapter myda; 
DataSet ds; 
String strConn; 
private void Page_Load(object sender, System.EventArgs e) 
     if (!IsPostBack) 
     { 
          strConn="Data Source=localhost;uid=sa;pwd=;Initial Catalog=northwind"; 
          mycn = new SqlConnection(strConn); 
          myda = new SqlDataAdapter ("Select * FROM Products ", mycn); 
          ds = new DataSet(); 
          myda.Fill (ds,"Table"); 
                     
          for(int i = 0 ;i < ds.Tables[0].Rows.Count - 1;i++) 
          { 
               listBox1.Items.Add (new ListItem(ds.Tables[0].Rows[i]["UnitPrice"].ToString(), 
               ds.Tables[0].Rows[i]["ProductID"].ToString())); 
               if(Convert.ToDouble(ds.Tables[0].Rows[i]["UnitPrice"].ToString()) <= 25 ) 
               { 
                    listBox1.Items[i].Attributes.Add("style", "color:red"); 
               } 
               else 
               { 
                    listBox1.Items[i].Attributes.Add("style", "color:green"); 
               } 
          } 
     } 



19.8 How to select all the Items from a listbox when the user selects a radio button?




<asp:listbox id="ListBox1" runat="server" selectionmode="Multiple"> 
     <asp:listitem value="Red">Red</asp:listitem> 
     <asp:listitem value="Blue">Blue</asp:listitem> 
     <asp:listitem value="Green">Green</asp:listitem> 
     <asp:listitem value="White">White</asp:listitem> 
</asp:listbox> 
<asp:radiobutton id="RadioButton1" runat="server" groupname="selrb" text="Select All" autopostback="True"></asp:radiobutton> 


VB.NET

Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged 
      Dim lstItem As ListItem 
      For Each lstItem In ListBox1.Items 
           lstItem.Selected = True 
      Next 
End Sub 



C#

foreach (ListItem lstItem in ListBox1.Items) 
     lstItem.Selected = true; 



19.9 How to use a single DataReader associated with two different tables to databind two different listbox controls?



VB.NET

Dim cn As SqlConnection 
Dim cmd As SqlCommand 
Dim dr As SqlDataReader 
cn = New SqlConnection("Server=localhost;uid=sa;database=northwind;pwd=") 
cmd = New SqlCommand("select * from products;select * from categories", cn) 
cn.Open() 
dr = cmd.ExecuteReader() 
ListBox1.DataSource = dr 
ListBox1.DataTextField = "productname" 
ListBox1.DataBind() 
dr.NextResult() 
ListBox2.DataSource = dr 
ListBox2.DataTextField = "categoryname" 
ListBox2.DataBind() 


C#

SqlConnection cn; 
SqlCommand cmd; 
SqlDataReader dr; 
cn = new SqlConnection("Server=localhost;uid=sa;database=northwind;pwd="); 
cmd= new SqlCommand ("select * from products;select * from categories", cn); 
cn.Open(); 
dr = cmd.ExecuteReader(); 
ListBox1.DataSource = dr; 
ListBox1.DataTextField = "productname"; 
ListBox1.DataBind(); 
dr.NextResult(); 
ListBox2.DataSource = dr; 
ListBox2.DataTextField = "categoryname"; 
ListBox2.DataBind(); 



19.10 How to clear all the items in a listbox?

  

VB.NET

ListBox1.Items.Clear 


C#

ListBox1.Items.Clear(); 

No comments :

Post a Comment