Introduction
In this example, I will explain how to do searching, filtering, sorting and moving the items between two ListBox
es and make it a reusable user control using Generic Collection IList
in ASP.NET (C#).
Generic collection
is used to bind the ListBox
es with any Generic type IList
and also explain how to bind both ListBox
es and remove all the existing records from the Source Listbox
which already exists in Destination Listbox
if in case you need to update the existing records which are already saved in database.
Background
Almost all web applications have security module to gives grants and privileges to the users. In this scenario, developers require two Listbox
es for available permissions and granting permission. They need lots of effort to develop the functionality every time in their application.
Source Code
In the first part, explain how to develop the user control using two ListBox
es and add the functionality of these two ListBox
es. After that, we will add the user control in a page and call it .
User Control Code
- Create a new website in .NET 2008 and add the user control from add new item from the solution. Name it
ucListBox
.
ASCX Code
<%@ Control Language="C#" AutoEventWireup="false"
CodeBehind="ucListBox.ascx.cs" Inherits="ListBox_Demo.ucListBox" %>
<script type="text/javascript" language="javascript">
var ddlText, ddlValue, ddl, lblMesg;
function CacheItems() {
ddlText = new Array();
ddlValue = new Array();
ddl = document.getElementById("<%=lstAvailable.ClientID %>");
for (var i = 0; i < ddl.options.length; i++) {
ddlText[ddlText.length] = ddl.options[i].text;
ddlValue[ddlValue.length] = ddl.options[i].value;
}
}
window.onload = CacheItems;
function FilterItems(value) {
ddl.options.length = 0;
for (var i = 0; i < ddlText.length; i++) {
if (ddlText[i].toLowerCase().indexOf(value) != -1) {
AddItem(ddlText[i], ddlValue[i]);
}
}
if (ddl.options.length == 0) {
AddItem("", "");
}
}
function AddItem(text, value) {
var opt = document.createElement("option");
opt.text = text;
opt.value = value;
ddl = document.getElementById("<%=lstAvailable.ClientID %>");
ddl.options.add(opt);
}
</script>
<table width="100%" border="0" id="tblSearch" runat="server" visible="true">
<tr>
<td style="width: 19%; height: 24px;" align="left" runat="server" id="tdd">
<span style="font-size: 8pt"><strong>
<asp:Label runat="server" Text="Search" ID="lblSearch"></asp:Label>
</strong></span>
</td>
<td>
<asp:TextBox ID="txtSearch" runat="server"
onkeyup="FilterItems(this.value)"></asp:TextBox><br />
</td>
</tr>
</table>
<table width="80%" border="0">
<tr align="left">
<td align="left">
<table width="100%">
<tr>
<td valign="top">
<table border="0" width="100%">
<tr>
<td>
<span style="font-size: 8pt"><strong>
<asp:Label runat="server"
ID="lblAvailable" Text="Available"></asp:Label>
</strong></span>
</td>
</tr>
<tr>
<td style="height: 200px">
<asp:ListBox ID="lstAvailable"
runat="server" Height="100%" SelectionMode="Multiple"
Width="300px" Font-Size="10pt"></asp:ListBox>
</td>
</tr>
</table>
</td>
<td align="center" valign="top">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<br />
</td>
</tr>
<tr>
<td>
<br />
</td>
</tr>
<tr>
<td>
</td>
</tr>
<tr>
<td>
<asp:ImageButton ID="btnAddAll"
ImageUrl="~/Images/GrantAll.png"
runat="server" CausesValidation="False" />
</td>
</tr>
<tr>
<td>
<asp:ImageButton ID="btnAdd"
ImageUrl="~/Images/Grant.png"
runat="server" CausesValidation="False" />
</td>
</tr>
<tr>
<td>
<asp:ImageButton ID="btnRemove"
ImageUrl="~/Images/Revoke.png"
runat="server" CausesValidation="False" />
</td>
</tr>
<tr>
<td>
<asp:ImageButton ID="btnRemoveAll"
ImageUrl="~/Images/RevokeAll.png" runat="server"
CausesValidation="False" />
</td>
</tr>
</table>
</td>
<td valign="top">
<table width="100%">
<tr>
<td>
<span style="font-size: 8pt"><strong>
<asp:Label runat="server"
ID="lblAdded" Text="Added"></asp:Label>
</strong></span>
</td>
</tr>
<tr>
<td style="height: 200px">
<asp:ListBox ID="lstAdded"
runat="server" Font-Size="10pt"
Height="100%" SelectionMode="Multiple"
Width="300px"></asp:ListBox>
</td>
</tr>
<tr>
<td>
</td>
</tr>
</table>
</td>
<td>
<table width="100%">
<tr>
<td>
<asp:ImageButton ID="btnMoveUp"
runat="server" ImageUrl="~/Images/MoveUp.png"
CausesValidation="False" />
</td>
</tr>
<tr>
<td>
<asp:ImageButton ID="btnMoveDown"
runat="server" CausesValidation="False"
ImageUrl="~/Images/MoveDown.png" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
In the above code, I added one label and text box for searching and filtering the records in the available ListBox
called lstAvailable.
I have used two listbox
es - lstAvailable
and lstAdded
, Move, Next, Pervious, First, Up and Down buttons for moving and sorting the items between the ListBox
es.
The above three JavaScript methods take care of the Filtering and Searching process. The details of these methods is described below:
CacheItems
This method is called on the window onload
event. The job of this method is to populate text and value arrays that will be used to cache the ListBox
items of Available List.
FilterItems
This method is called when keyup
event fires in the Search TextBox. This method searches for the string
segment and filters the ListBox
items of Available List.
AddItem
This method is used to add a new item in the ListBox
.
C# Code
Add the System.Collections
in code behind and add the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
namespace ListBox_Demo
{
public partial class ucListBox : System.Web.UI.UserControl
{
#region Property
private IList _DataSourceAvailable = null;
private IList _DataSourceAdded = null;
private string _dataTextFieldAvailable = string.Empty;
private string _dataValueFieldAvailable = string.Empty;
private string _dataTextFieldAdded = string.Empty;
private string _dataValueFieldAdded = string.Empty;
private string _availableItemText = "Available Roles";
private string _addedItemText = "Assgin Roles";
protected ArrayList arlList = new ArrayList();
public string AvailableItemHeaderText
{
get { return _availableItemText; }
set { _availableItemText = value; }
}
public string AddedItemsHeaderText
{
get { return _addedItemText; }
set { _addedItemText = value; }
}
public ListItemCollection AvailableItems
{
get { return lstAvailable.Items; }
}
public ListItemCollection AddedItems
{
get { return lstAdded.Items; }
}
public IList DataSourceAvailable
{
get { return _DataSourceAvailable; }
set { _DataSourceAvailable = value; }
}
public IList DataSourceAdded
{
get { return _DataSourceAdded; }
set { _DataSourceAdded = value; }
}
public string DataTextFieldAvailable
{
get { return _dataTextFieldAvailable; }
set { _dataTextFieldAvailable = value; }
}
public string DataValueFieldAvailable
{
get { return _dataValueFieldAvailable; }
set { _dataValueFieldAvailable = value; }
}
public string DataTextFieldAdded
{
get { return _dataTextFieldAdded; }
set { _dataTextFieldAdded = value; }
}
public string DataValueFieldAdded
{
get { return _dataValueFieldAdded; }
set { _dataValueFieldAdded = value; }
}
#endregion
#region Method
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Initializer();
}
private void Initializer()
{
btnAdd.Click += new ImageClickEventHandler(btnAdd_Click);
btnAddAll.Click += new ImageClickEventHandler(btnAddAll_Click);
btnRemove.Click += new ImageClickEventHandler(btnRemove_Click);
btnRemoveAll.Click += new ImageClickEventHandler(btnRemoveAll_Click);
btnMoveUp.Click += new ImageClickEventHandler(btnMoveUp_Click);
btnMoveDown.Click += new ImageClickEventHandler(btnMoveDown_Click);
}
public void BindAvailableList()
{
lblAdded.Text = this.AddedItemsHeaderText;
lblAvailable.Text = this.AvailableItemHeaderText;
lstAvailable.DataSource = this.DataSourceAvailable;
lstAvailable.DataTextField = this.DataTextFieldAvailable;
lstAvailable.DataValueField = this.DataValueFieldAvailable;
lstAvailable.DataBind();
}
public void BindAddedList()
{
lblAdded.Text = this.AddedItemsHeaderText;
lblAvailable.Text = this.AvailableItemHeaderText;
lstAdded.DataSource = this.DataSourceAdded;
lstAdded.DataTextField = this.DataTextFieldAdded;
lstAdded.DataValueField = this.DataValueFieldAdded;
lstAdded.DataBind();
}
public void BindList()
{
lblAdded.Text = this.AddedItemsHeaderText;
lblAvailable.Text = this.AvailableItemHeaderText;
lstAdded.DataSource = this.DataSourceAdded;
lstAdded.DataTextField = this.DataTextFieldAdded;
lstAdded.DataValueField = this.DataValueFieldAdded;
lstAdded.DataBind();
lstAvailable.DataSource = this.DataSourceAvailable;
lstAvailable.DataTextField = this.DataTextFieldAvailable;
lstAvailable.DataValueField = this.DataValueFieldAvailable;
lstAvailable.DataBind();
#region Remove intersection Record
ArrayList ary = new ArrayList();
for (int i = 0; i < lstAvailable.Items.Count; i++)
{
for (int j = 0; j < lstAdded.Items.Count; j++)
{
if (lstAvailable.Items[i].Value == lstAdded.Items[j].Value)
{
if (!ary.Contains(lstAvailable.Items[i]))
{
ary.Add(lstAvailable.Items[i]);
j = -1;
}
break;
}
}
}
for (int i = 0; i < ary.Count; i++)
{
lstAvailable.Items.Remove(((ListItem)ary[i]));
}
#endregion
ScriptManager.RegisterStartupScript(this.Page, typeof(Page), "myscript", "CacheItems();", true);
}
#endregion
#region Navigation
protected void btnAdd_Click(object sender, EventArgs e)
{
if (lstAvailable.SelectedIndex >= 0)
{
for (int i = 0; i < lstAvailable.Items.Count; i++)
{
if (lstAvailable.Items[i].Selected)
{
if (!arlList.Contains(lstAvailable.Items[i]))
arlList.Add(lstAvailable.Items[i]);
}
}
for (int i = 0; i < arlList.Count; i++)
{
if (!lstAdded.Items.Contains((ListItem)arlList[i]))
lstAdded.Items.Add((ListItem)arlList[i]);
lstAvailable.Items.Remove((ListItem)arlList[i]);
}
}
}
protected void btnAddAll_Click(object sender, EventArgs e)
{
foreach (ListItem list in lstAvailable.Items)
{
lstAdded.Items.Add(list);
}
lstAvailable.Items.Clear();
}
protected void btnRemove_Click(object sender, EventArgs e)
{
if (lstAdded.SelectedIndex >= 0)
{
for (int i = 0; i < lstAdded.Items.Count; i++)
{
if (lstAdded.Items[i].Selected)
{
if (!arlList.Contains(lstAdded.Items[i]))
arlList.Add(lstAdded.Items[i]);
}
}
for (int i = 0; i < arlList.Count; i++)
{
if (!lstAvailable.Items.Contains((ListItem)arlList[i]))
lstAvailable.Items.Add((ListItem)arlList[i]);
lstAdded.Items.Remove((ListItem)arlList[i]);
}
}
}
protected void btnRemoveAll_Click(object sender, EventArgs e)
{
foreach (ListItem list in lstAdded.Items)
{
lstAvailable.Items.Add(list);
}
lstAdded.Items.Clear();
}
void btnMoveDown_Click(object sender, ImageClickEventArgs e)
{
try
{
int startindex = lstAdded.Items.Count - 1;
for (int i = startindex; i > -1; i--)
{
if (lstAdded.Items[i].Selected)
{
if (i < startindex && !lstAdded.Items[i + 1].Selected)
{
ListItem bottom = lstAdded.Items[i];
lstAdded.Items.Remove(bottom);
lstAdded.Items.Insert(i + 1, bottom);
lstAdded.Items[i + 1].Selected = true;
}
}
}
}
catch (Exception ex)
{
}
}
void btnMoveUp_Click(object sender, ImageClickEventArgs e)
{
try
{
for (int i = 0; i < lstAdded.Items.Count; i++)
{
if (lstAdded.Items[i].Selected)
{
if (i > 0 && !lstAdded.Items[i - 1].Selected)
{
ListItem bottom = lstAdded.Items[i];
lstAdded.Items.Remove(bottom);
lstAdded.Items.Insert(i - 1, bottom);
lstAdded.Items[i - 1].Selected = true;
}
}
}
}
catch (Exception ex)
{
}
}
#endregion
}
}
The above mentioned three binds functions are used to bind ListBox
and each one has a different functionality whose description is given below.
BindAvailableList()
If you want to bind the Available ListBox
, then call this method form the aspx page and its required following properties should be assigned from the aspx page:
DataSourceAvailable
: Pass the IList
CollectionDataTextFieldAvailable
: Its required Property Name which shows in the ListBox
DataValueFieldAvailable
: Its required Property ID which should be unique in the ListBox
BindAddedList()
If you want to bind the Added ListBox
, then call this method form the aspx page and its required following properties should be assign from the aspx page.
DataSourceAdded
: Pass the IList
CollectionDataTextFieldAdded
: Its required Property Name which shows in the ListBox
DataValueFieldAdded
: Its required Property ID which should be unique in the ListBox
BindList()
If you want to bind both ListBox
es Available
and Added
and need to remove all the items which already exist in the Added ListBox
, then call this function from the aspx page and its required following properties should be assigned from the aspx page.
DataSourceAvailable
: Pass the IList
CollectionDataTextFieldAvailable
: Its required Property Name which shows in the ListBox
DataValueFieldAvailable
: Its required Property ID which should be unique in the ListBox
DataSourceAdded
: Pass the IList
CollectionDataTextFieldAdded
: Its required Property Name which shows in the ListBox
DataValueFieldAdded
: Its
required Property ID which should be unique in the ListBox
Note
AvailableItemHeaderText
and AddedItemsHeaderText
are optional, It will be required if you want to change the heading of Listbox
es from aspx page.
GUI Page Code
Aspx Code
Add the ucListBox
user control in default.aspx page which is automatically added in the website when you created it in .NET 2008.
<%@ Register src="ucListBox.ascx" tagname="ucListBox" tagprefix="uc1" %>
To show the complete working of user control, I have created three buttons in a page and call user control all three binds methods.
<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="ListBox_Demo._Default" %>
<%@ Register src="ucListBox.ascx" tagname="ucListBox" tagprefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAvailable" runat="server" Text="Bind Available List"
onclick="btnAvailable_Click" />
<asp:Button ID="btnAdded" runat="server" Text="Bind Added List"
onclick="btnAdded_Click" />
<asp:Button ID="btnBoth" runat="server" Text="Bind Both"
onclick="btnBoth_Click" />
<uc1:ucListBox ID="ucListBox1" runat="server" />
</div>
</form>
</body>
</html>
C# Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
namespace ListBox_Demo
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
void AvailableItems()
{
List<Roles> lstRole = new List<Roles>();
Roles objRoles = new Roles();
objRoles.ID = 1;
objRoles.Name = "Admin";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 2;
objRoles.Name = "Manager";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 3;
objRoles.Name = "Supervisor";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 4;
objRoles.Name = "Employee";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 5;
objRoles.Name = "User";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 6;
objRoles.Name = "Client";
lstRole.Add(objRoles);
ucListBox1.DataTextFieldAvailable = "Name";
ucListBox1.DataValueFieldAvailable = "ID";
ucListBox1.DataSourceAvailable = lstRole;
ucListBox1.AvailableItemHeaderText = "Available Permissions";
ucListBox1.AddedItemsHeaderText = "Added Permissions";
}
void SelectedItems()
{
List<Roles> lstRole = new List<Roles>();
Roles objRoles = new Roles();
objRoles.ID = 1;
objRoles.Name = "Admin";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 2;
objRoles.Name = "Manager";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 4;
objRoles.Name = "Employee";
lstRole.Add(objRoles);
objRoles = new Roles();
objRoles.ID = 5;
objRoles.Name = "User";
lstRole.Add(objRoles);
ucListBox1.DataTextFieldAdded = "Name";
ucListBox1.DataValueFieldAdded = "ID";
ucListBox1.DataSourceAdded = lstRole;
ucListBox1.AvailableItemHeaderText = "Available Permissions";
ucListBox1.AddedItemsHeaderText = "Added Permissions";
}
protected void btnAvailable_Click(object sender, EventArgs e)
{
AvailableItems();
ucListBox1.BindAvailableList();
}
protected void btnAdded_Click(object sender, EventArgs e)
{
SelectedItems();
ucListBox1.BindAddedList();
}
protected void btnBoth_Click(object sender, EventArgs e)
{
AvailableItems();
SelectedItems();
ucListBox1.BindList();
}
}
public class Roles
{
public int ID { get; set; }
public string Name { get; set; }
}
}
I have created two functions, SelectedItems()
and AvailableItems()
to fill the hard code List and call it on three different button clicks.
Points of Interest
It was annoying writing these examples since they are too big and took up a lot of my time.