Why are my listboxitems not debited?

If I clicked an item in the middle of the list, I expect that all but 1 item will be collapsed. The actual conclusion is that there are many elements left. What for? This is the whole 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> 
+6
source share
2 answers

I believe this is due to the use of ItemContainerGenerator.ContainerFromItem .

ListBox uses VirtualizingStackPanel by default. Thus, elements that do not appear on the screen when the window loads are not yet created. Setting them to Collapsed does not affect as soon as they return to the screen.

You can play a little by changing the initial height of the Window . If you set it to 550 or so, it works as expected. If you set 150 or so, you will have many elements that are still visible.

One thing you can do to change this, if you don't have as many items, just change the ItemsPanel .

+7
source

You probably need to disable virtualization . ListBoxItems will not be created by default until needed. When you discard the visible ListBoxItems, you free up space for more that will be created after your code runs.

Add this to your list:

 VirtualizingStackPanel.IsVirtualizing="False" 

Or you can probably use a style to smooth out such elements:

 <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Style.Triggers> <Trigger Property="IsSelected" Value="False"> <Setter Property="Visibility" Value="Collapsed" /> </Trigger > </Style.Triggers> </Style> </ListBox.ItemContainerStyle> 
+4
source

Source: https://habr.com/ru/post/889031/


All Articles