且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么不是我的listboxitems崩溃吗?

更新时间:2023-01-23 17:24:19

我相信它,因为你使用的 ItemContainerGenerator.ContainerFromItem



的ListBox 正在使用 VirtualizingStackPanel 默认情况下。所以,当你加载窗口不在屏幕上的项目尚未创建。将它们设置为折叠有一次,他们带回来的屏幕没有任何影响。



您可以玩弄这个改变窗口的初始高度一点点。如果你把它设置为550左右,它按预期工作。如果你把它设置为150左右,你就会有元素仍然可见不少。



一件事你可以做些什么来改变这一点,如果你不打算有很多元素是刚刚修改 ItemsPanel


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>

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.