Skip to content

How to Retrieve a GridView Based on a CheckBoxList of Items with Asp.Net using ObjectDataSource with a little LINQ Thrown In

Updated: at 11:17 PM

So, the problem is you have a list that you want to retrieve from that contains multiple values.  Say for example, you have a list of 5 cities and you want to retrieve a list of people in some combination of those cities.  If you use the class SelectValue method with GridView you run out of steam because it's only one value.  What you'd really like to do is pass the CheckBoxList into the GridView as a selection parameter, but unfortunately, when you do that, you just get the one selected value from the CheckBoxList, not all the values.

I'm sure you can make a custom ControlParameter in ObjectDataSource to solve this, but I really don't have time for that.  I just wanted something quick (which I now have and thought I'd share).

Basically, what I did was create an invisible label on my GridView that will get the string of values I want to retrieve, then, my ObjectDataSource gets one value (the string) and parses it into small values.  My plan is to do a quick run through of the code here, but then also post the project so you can see for yourself how it works.

Here we go.

First, let's make a simple BusinessObject class that returns to us some data.  The basic object that will be returned is the Person defined as follows:

 public class Person
    {
        public Person()
        {
        }
 
        public Person(string _name, int _id)
        {
            this._name = _name;
            this._id = _id;
        }
 
        private string _name;
        private int _id;
 
        public string name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        public int id
        {
            get { return _id; }
            set { _id = value; }
        }
    }

Next, we need two methods, the first is the method that does the heavy lifting (that is, takes a list of integers and returns the final list of people who have those cities in them, then, we need the method that polymorphically calls (did I spell that wrong, live writer thinks so... sorry) that method whose input is a single string.  That method parses the string (which was assembled in page_load of the calling page) and calls the first one.

So, here is the method ObjectDataSource actually calls to get it's view of the data (remember, ObjectDataSource only returns one view).

 public List<Person> GetPeopleByCityList(List<int> cityList)
        {
            List<Person> personList = new List<Person>
                                          {
                                              new Person("Peter_SanJose", 1),
                                              new Person("Tom_Hartsdale", 2),
                                              new Person("Eric_Chicago", 3),
                                              new Person("Ron_SanJose", 1),
                                              new Person("John_Chicago", 3),
                                              new Person("Charly_Scarsdale", 4)
                                          };
 
            var personResult = from p in personList
                               where cityList.Contains(p.id)
                               orderby p.name
                               select p;
 
            return personResult.ToList();
        }
 
        public List<Person> GetPeopleByCityListString(string cityListString)
        {
            if (!String.IsNullOrEmpty(cityListString))
            {
                var values = cityListString.Split(';');
                var cityList = new List<int>();
                foreach (string s in values)
                {
                    cityList.Add(Convert.ToInt32(s));
                }
 
                return GetPeopleByCityList(cityList);
            }
            return null;
        }
 
    }

Now, the method that actually does the work.  Notice I'm using the C# 3.0 object initializer syntax to build it, but normally, you'd be calling a database or something like that here.  Also notice the clever LINQ that does the equivalent of an SQL IN clause.  That is, we'd normally be doing something like "Select .. From Person Where CityId IN (1,3..)).  It seems a little backwards to me, but it does the job.

So, now we have the business object, let's put it to work.  Let's build a simple aspx page that has a CheckBoxList, GridView,Label and a Button.  I'll pre-populate the CheckBoxList just to keep my example simple.  Normally, you'd be getting that data from another data source like a database.

So, Here is the aspx file we built.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body bgcolor="#00ccff">
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="ButtonSearch" runat="server" Text="Retrieve" 
            onclick="ButtonSearch_Click" />
        <asp:Label ID="Label1" runat="server" Visible="false" Text="Label"></asp:Label>
        <asp:CheckBoxList ID="CheckBoxList1" runat="server">
            <asp:ListItem Value="2">Hartsdale</asp:ListItem>
            <asp:ListItem Value="4">Scarsdale</asp:ListItem>
            <asp:ListItem Value="3">Chicago</asp:ListItem>
            <asp:ListItem Value="1">San Jose</asp:ListItem>
        </asp:CheckBoxList>
        <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetPeopleByCityListString"
            TypeName="BO.BusinessObject">
            <SelectParameters>
                <asp:ControlParameter ControlID="Label1" Name="cityListString" PropertyName="Text"
                    Type="String" />
            </SelectParameters>
        </asp:ObjectDataSource>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
            DataSourceID="ObjectDataSource1">
            <Columns>
                <asp:BoundField DataField="name" HeaderText="name" SortExpression="name" />
                <asp:BoundField DataField="id" HeaderText="id" SortExpression="id" />
            </Columns>
        </asp:GridView>
    </div>
    </form>
</body>
</html>

Notice that the asp controlparameter is passing the Label1 contents to the ObjectDataSource.  To load that, we need to put some code in the Page_Load event that will set that line.  Here is that code.  It simply reads the checkboxlist and builds the string of numbers (3,5,7,9.).

I'm pretty sure that is it.  Now, when you run the web site, you'll get a screen that you can click multiple checkboxes on and get all the results that correspond with that checkbox.  Here is what it should look like:

image_thumb1

Hope this Helps!  And, if you it the better way by making a custom ControlParameter, post it here and we can all ignore this article.  Smile