Ik geef training in frontend tools en stacks als HTML, JavaScript, TypeScript, React, Angular en Vue. Ik schrijf boeken en artikelen over tal van (ICT-) onderwerpen. Ik was lead developer en directeur bij Yindo - Jouw digitale bibliotheek. Je kunt mij volgen op Twitter(@PeterKassenaar).

In dit blog vind je persoonlijke artikelen, die niet noodzakelijk tech-gerelateerd zijn.

Views and expressions are my own.

Terug naar de algemene site.

02juli

Counting selected items in a List Control using Linq

In my previous blog post I wrote about a method I found on clearing all items in a List Control using the (apparently) built-in method ClearSelection().

In this post I discuss a small technique some of you might also find useful. Besides clearing the items in a list control it was also necessary for the before mentioned application to count the number of selected items in a List Control (mosty a <asp:CheckBoxList>). In some lists users where restricted to selecting a maximum of 5 items out of 10, or similar. If a user selects a sixth item, an error message is shown.

Traditional approach using foreach()

The traditional approach would be something like the code below.

First, declare the CheckBoxList on the page like this

<asp:CheckBoxList runat="server" ID="chkList" RepeatColumns="2" RepeatDirection="Vertical"

AutoPostBack="true" OnSelectedIndexChanged="chkListChanged" />
<
asp:Label ID="lblNoItems" runat="server" />

For the sake of the example I use the Page_Load() event in code behind to fill the list with 20 items:

 protected void Page_Load(object sender, EventArgs e)

    {

        if (!Page.IsPostBack)

        {

            // fill items in CheckBoxList

            for (int i = 1; i <= 20; i++)

            {

                ListItem li = new ListItem();

                li.Text = string.Format("Item {0}", i);

                li.Value = i.ToString();

                chkList.Items.Add(li);

            }

        }

    }

Then, write the method chkListChanged() to handle the selection of the items.

protected void chkListChanged(object sender, EventArgs e)
{

int selectedItems = 0;

       foreach (ListItem li in chkList.Items)

        {

            if (li.Selected)

                selectedItems++;

        }

        if (selectedItems > 5)

        {

            // throw some error message

            lblNoItems.Text = " Too many items selected...";

        }
}

An approach using Linq

Since the project I'm working on is a full .NET 3.5 Linq-based solution, I figured it would be elegant to use Linq also to retrieve the number of selected items in the List. This way it is like "querying a List Control". This is (IMHO) quite an exciting concept, if you were used to only build queries for SQL-databases. After some googling I composed the following method

var total = from i in chkList.Items.Cast<ListItem>()

                    where i.Selected == true

                    select i;

now the variable total is available. It holds all the selected items in the list. We can use the Linq method Count() to test how many items have been selected and show an appropriate message in lblNoItems.

int allowedItems = 5;       

        lblNoItems.Text = total.Count() <= allowedItems

            ? string.Format("No. of selected items: {0}. You're OK!", total.Count())

            : string.Format("To many items selected ({0}), please deselect {1} item(s)!",

                total.Count(), (total.Count() - allowedItems));

Two things to notice here:

  • In the Linq query you must explicitly cast the items in the List to a <ListItem> object using the Cast() method, otherwise the query won't work.
  • I use the ? : operator to decide wich message is shown instead of an if-else compound statement.

As I've discovered, there are more advantages using Linq this way. For example, the variable total not only holds the number of selected items in the list (as the variable selectedItems does in the traditional approach), but is a complete array of all selected ListItem objects. You could further manipulate this, for example serialize them and store in a users profile or in a database, and so on (again, using a foreach-loop).

This is what the page looks like when 5 items or less are selected

And here's the UI once you select a sixth item

The files are available for download,

Thanks for reading,

-- Peter Kassenaar,
2 juli 2008.

countCheckBoxList.zip (1,56 kb)

27juni

Clearing all items in a List Control

I am currently working on an ASP.NET project where the client needs to have a web form with about ten lists, each list containing anywhere from three or four to a couple of dozen options.

These lists are composed as a CheckBoxList, RadioButtonList or DropDownList, all based on the standard <asp:xxxList> control.

The selected items in the lists are used to build a Linq statement to query and filter a large database table. The (concept) UI of these lists are like the image below.

Clearing the list

In order to begin a new query, we figured it would be handy to have a button below each list to clear the selection of all items instead of manually deselecting every option. So I added a Clear button ('Leegmaken' in Dutch) and wrote the following code for the button. Sure, I looked through the Intellisense list for something like 'empty', or, 'deselect', but couldn't find anything.

So I assumed this was the easiest way to set the Selected state of every ListItem to false. Have a foreach() loop and loop through every ListItem in the control, setting the Selected property to false. (The bindConditionalGrid() method below the loop is for binding the GridView in the page again, to reflect the new criteria.)

Until yesterday.

ClearSelection()

By accident I was looking at the Intellisense list for a CheckBoxList control, when I stumbled upon the ClearSelection() method, which apparently had the exact same function as the little method I wrote above!

So now instead of four lines of code, I need only one. And this times ten, for the number of Clear-buttons in the page (I know, I think it is possible to write a generic method to clear a list and pass the button name or list name as a parameter, but this quick and dirty approach is suitable for now. If you have such a method, feel free to share it via a comment below :-).

Here is the MSDN page with the documentation for the ClearSelection method:

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.clearselection.aspx 

Bottomline

Intellisense is your friend.

There might be prewritten methods for a task that you wish to accomplish. They might have other names than you expect :-), especially when English is not your mother tongue.

Peter Kassenaar
-- 27 juni 2008