0

I need to programatically select a subset of ListBoxItems in a ListBox (SelectedMode=Multiple) control.

<Grid x:Name="LayoutRoot" Background="White">
    <ListBox Height="238" HorizontalAlignment="Left" Margin="26,41,0,0" Name="listBox1" VerticalAlignment="Top" Width="349" SelectionMode="Multiple" />
    <Button Content="Fill" Height="23" HorizontalAlignment="Left" Margin="26,12,0,0" Name="buttonFill" VerticalAlignment="Top" Width="75" Click="buttonFill_Click" />
    <Button Content="Randomly Select" Height="23" HorizontalAlignment="Left" Margin="116,12,0,0" Name="buttonSelectRandom" VerticalAlignment="Top" Width="104" Click="buttonSelectRandoml_Click" />
</Grid>


    private void buttonFill_Click(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < 100; i++)
            listBox1.Items.Add(new ListBoxItem { Content = i.ToString()});
    }

    private void buttonSelectRandom_Click(object sender, RoutedEventArgs e)
    {
        var rand = new Random();

        foreach (ListBoxItem item in listBox1.Items)
            if (rand.Next(2)==1) item.IsSelected = true; 
    }

However it seems that only the currently visible items show as selected when I run the code (click the "Fill" button and then the "Randomly Select" button). Scrolling through the ListBox shows no other ListBoxItems as selected even though a check of their "IsSelected" state in code will show them set to "true".

Interestingly, if I manually scroll to the end of the ListBox (or part way) first and then click the "Randomly Select" button then the ListBox will draw all the selected items correctly . I have tried many workarounds but can't seem to find one that works. Is this a bug? Any workarounds?

Thanks for your help.

Jink

1 Answer 1

3

this might be because the ListBox's using VirtualizingStackPanel. Can you test it with a normal StackPanel?

    <ListBox>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

Edit:

Another solution is, instead of doing item.IsSelected = true, you do

        foreach (int item in listBox1.Items)
        {
            if (rand.Next(2) == 1)
            {
                this.listBox1.SelectedItems.Add(item);
            }
        }

I have tested it and it works. :)

Sign up to request clarification or add additional context in comments.

6 Comments

+1 This worked for me. It also explains why scrolling through the list before setting the selections causes the items to display properly.
@Xin, I can't accept the answer, as it's not my question. :) I bumped it because it's not clear from your answer whether you had tried that code yourself, but it does work to fix that particular issue. Anyway, in case the OP actually needs a virtualizing items panel because of memory-intensive items, I hope they will leave the question open for a few days and give many people a chance to weigh in with other possible workarounds.
+1 Thanks @Xin, that works. Hmmm, the VirtualizingStackPanel - I'll have to take a look at that. I'll take @Kimberly 's advice and leave it open for a while before accepting your answer to see if there is a good way to do it with the VirtualizingStackPanel or some such in place because I could have a lot of items in the list and performance might benefit.
Hi, I have updated the answer and hopefully this time it will work even with the VirtualizingStackPanel. Interestingly, I have found your original code works in WPF. That means once those invisible ListBoxItems are scrolled into view, they will be selected automatically. However this is not the case in Silverlight.
Excellent @Xin. Tested your second code batch and can confirm that it does work with the VirtualizingStackPanel in my Silverlight project. I would be interested to know what's behind this WPF\Silverlight behavioral difference.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.