views:

4647

answers:

5

I'm trying to build an "edit" page for a database record that can be edited and saved back to the database. One of the fields will be a multi-select listbox that will need to highlight the appropriate list items in a hard-coded list when loaded.

Using C#, how do I populate a multi-select listbox -- with the appropriate items selected -- based on the comma-delimited string from a database field? I've researched a few solutions that involve loops, but I have been unable to get them to work with my limited C# skillset.

This is all I have now, before I got stuck. You'll see that it doesn't account for multiple values in the string. Is there a function like "contains" that I can check to see if the value matches? I'm still missing some (probably basic) C# logic and coding here.

int i;
for (i = 0; i <= CATEGORYListBox.Items.Count - 1; i++)
{
    if (reader["CATEGORY"].ToString() == CATEGORYListBox.Items(i).Value)
    {
        CATEGORYListBox.Items(i).Selected = True;                   
    }
}

...

<asp:ListBox ID="CATEGORYListBox" runat="server">
    <asp:ListItem Value="Circulation">Circulation</asp:ListItem>
    <asp:ListItem Value="Interactive Media">Interactive Media</asp:ListItem>
    <asp:ListItem Value="Classified">Classified</asp:ListItem>
    <asp:ListItem Value="Publishing">Publishing</asp:ListItem>
    <asp:ListItem Value="Editorial">Editorial</asp:ListItem>
    <asp:ListItem Value="Retail">Retail</asp:ListItem>
 </asp:ListBox>

Thanks everyone.

A: 

This is brute force and ugly, but it should work. It looks like your code above is some sort of hybrid between VB and C#. The code below is C# only. Also, consider not doing your ADO.Net in your codebehind.

for (int i = 0; i < CATEGORYListBox.Items.Count; i++)
{
    foreach (string category in reader["CATEGORY"].ToString().Split(','))
    {
        if (category != CATEGORYListBox.Items[i].Value) continue;
        CATEGORYListBox.Items[i].Selected = true;
        break;
    }
}
Michael Meadows
Michael - this worked with a two minor fixes, 1) I had to append -1 to the .Count in the first line or it threw an out of range error, and 2) I had to use single quotes not double in the Split command. After that it worked like a charm, thanks!
Thanks. I edited the code to reflect the feedback.
Michael Meadows
+2  A: 

I would suggest something along these lines. It seems more readable than doing nested loops.

    List<string> categories = new List<string>(reader["CATEGORY"].ToString().Split(','));
    foreach (ListItem item in CATEGORYListBox.Items)
    {
        if (categories.Contains(item.Value))
            item.Selected = true;
    }
Jab
Jesse - I tried your too, but I kept getting the following error: "CS0246: The type or namespace name 'List' could not be found (are you missing a using directive or an assembly reference?)" Because I'm a little too new with C3 I didn't know where to go from there. But thanks anyway!
I believe you need to be using System.collections.Specialized leewebdev, or fully qualifying List<string> of course.
peacedog
List<T> is part of the System.Collections.Generic namespace. Add a using directive for this and you should be ok. The benefit of using the list is it makes code more readable, there is a very minor cost in overhead, though, but I wouldn't consider that a problem, since we shouldn't preoptimize. :)
Michael Meadows
peacedog and Michael are correct, the List<T> is in System.Collections.Generics. If you don't use them for this problem, you should still invest some time in learning them. They are a very important feature of the framework.
Jab
A: 

i need the same thing in a win form....but .selected is not showing up in intellisense....is it possible i am missing a using statement

leah, I'd need to see your code before I could comment further. But System.Windows.Controls.ListBox is just a little different than System.Web.UI.WebControls.ListBox, and IIRC that difference manifests in the Items collections for each controls.
peacedog
A: 

Another Solution for the problem is:

string[] arrSplitItems; arrSplitItems = TestsOrdrd.Split(','); if (arrSplitItems.Length > 0) { for (int iCount = 0; iCount < arrSplitItems.Length; iCount++) { lstTestcode.Items.FindByValue(arrSplitItems[iCount].ToString()).Selected = true;

        }
    }

TestsOrdrd contains the Selected values of Listbox.

Thanks, Rathika Krishnavelu

Rathika
A: 

The easiest implementation?

string sequenceFromDBorPostBack= "1,3,4,6,48";

foreach (ListItem item in lstLocations.Items)
{
     item.Selected = sequenceFromDBorPostBack.Split(',').Contains(item.Value);
}

I am not sure if this is performance effective..

Vaclav
Including the Split() in the loop might not be the most efficient. If the listbox is prepopulated, you will have to loop through each item as shown. If you are dynamically populating the list list, the selection check could be in that loop instead of separate one.
Brad Bruce
Thanks Brad, that makes sense. I will check it out in my code. I guess my solution is very nice and the code is clean but useful only in some circumstances.
Vaclav