Mikem
Mikem

Reputation: 59

Retrieve multiple keys from ListBox populated with Dictionary

I have a listbox populated with days of the week via a dictionary:

private Dictionary<int, string> Days()
{
    Dictionary<int, string> day = new Dictionary<int, string>();
    day.Add(1, "Sunday");
    day.Add(2, "Monday");
    day.Add(3, "Tuesday");
    day.Add(4, "Wednesday");
    day.Add(5, "Thursday");
    day.Add(6, "Friday");
    day.Add(7, "Saturday");
    return day;
}


private void SetDays()
{
    listBoxDays.DataSource = new BindingSource(Days(), null);
    listBoxDays.DisplayMember = "Value";
    listBoxDays.ValueMember = "Key";
    listBoxDays.SelectedIndex = 0;
}

The listbox is set up for multiselect, and I would like to grab all of the dictionary Keys from the selected items... Whenever I try to loop through I only get the value of the first key selected for the entire collection.

private void GatherDays()
{
    List<int> list = new List<int>();

    foreach (var item in listBoxDays.SelectedItems)
    {
        list.Add((int)listBoxDays.SelectedValue);
    }
}

It is easy to get a single selected item's key but I am having a very difficult time trying to get multiple selected.

Upvotes: 2

Views: 1226

Answers (1)

Habib
Habib

Reputation: 223257

Modify your GatherDays method like:

private void GatherDays()
{
    List<int> list = new List<int>();
    foreach (KeyValuePair<int, string> item in listBoxBuildDays.SelectedItems)
    {
        list.Add(item.Key);
    }
}

Or you can shorten your code using LINQ like:

List<int> list =listBoxBuildDays.SelectedItems
                    .OfType<KeyValuePair<int, string>>()
                    .Select(r => r.Key)
                    .ToList();

Currently the issue is due to:

 list.Add((int)listBoxDays.SelectedValue);

SelectedValue represents the selected value at lowest index in Items.

See: ListControl.SelectedValue Property

If multiple items are selected, the value of the selected item with the lowest index is returned. If no item is selected, an empty string ("") is returned.

That is why you are only seeing a single value in your list.

One more thing to add.

You can use DayOfWeek enumeration for your work instead of dictionary like:

In SetDays

private void SetDays()
{
    listBoxBuildDays.DataSource = Enum.GetValues(typeof(DayOfWeek));
    listBoxBuildDays.SelectedIndex = 0;
}

and in GatherDays

private void GatherDays()
{
    List<int> list = listBoxBuildDays
        .SelectedItems.Cast<DayOfWeek>()
        .Select(r => (int) r)
        .ToList();
}

But the only thing different would be number (index), this starts with 0, instead of 1 like in your dictionary.

Upvotes: 4

Related Questions