Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why don't my listboxitems collapse?

Tags:

c#

wpf

xaml

If I click an item in the middle of the list, I expect all but 1 element to be collapsed. The actual output is that many items are left. Why? This is the entire program.

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace WpfApplication2
{
    public partial class MainWindow : Window
    {
        public class obj { }

        public MainWindow()
        {
            InitializeComponent();
            List<obj> objList = new List<obj>();
            for (int i = 0; i < 30; i++) objList.Add(new obj());
            lb.ItemsSource = objList;
        }

        private void lb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox lb = sender as ListBox;
            for (int i = 0; i < lb.Items.Count; i++)
            {
                ListBoxItem tmp = (ListBoxItem)(lb.ItemContainerGenerator.ContainerFromItem(lb.Items[i]));
                if (tmp != null)
                {
                    if (tmp.IsSelected)
                        tmp.Visibility = System.Windows.Visibility.Visible;
                    else
                        tmp.Visibility = System.Windows.Visibility.Collapsed;
                }
            }
        }
    }
}


<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        >
    <Grid>
        <ListBox Name="lb" SelectionChanged="lb_SelectionChanged" IsSynchronizedWithCurrentItem="True" >
            <ListBox.ItemTemplate >
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Name="tb1" Text="whatever"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>
like image 938
patrick Avatar asked May 25 '11 18:05

patrick


2 Answers

I believe its because of your use of ItemContainerGenerator.ContainerFromItem.

The ListBox is using a VirtualizingStackPanel by default. So the items that aren't on the screen when you load the window are not created yet. Setting them to Collapsed has no effect once they're brought back on the screen.

You can play around with this a little bit by changing the initial height of the Window. If you set it to 550 or so, it works as expected. If you set it to 150 or so, you'll have A LOT of elements still visible.

One thing you can do to change this if you're not going to have that many elements is just change the ItemsPanel.

like image 105
Tim Avatar answered Sep 23 '22 12:09

Tim


You probably need to disable virtualization. The ListBoxItems will not be created by default, until needed. When you collapse the visible ListBoxItems, you make room for more, which will be created after your code is run.

Add this to your ListBox:

VirtualizingStackPanel.IsVirtualizing="False"

Or you could probably use a Style to collapse the items like so:

<ListBox.ItemContainerStyle>
     <Style TargetType="ListBoxItem">
         <Style.Triggers>
             <Trigger Property="IsSelected" Value="False">
                 <Setter Property="Visibility" Value="Collapsed" />
             </Trigger >
         </Style.Triggers>
     </Style>
</ListBox.ItemContainerStyle>
like image 32
CodeNaked Avatar answered Sep 24 '22 12:09

CodeNaked