如果我单击列表中间的某个项目,我希望除了1个元素之外的所有元素都会折叠。实际输出是剩下许多项目。为什么?这是整个计划。
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>
答案 0 :(得分:7)
我相信它是因为你使用了ItemContainerGenerator.ContainerFromItem
。
ListBox
默认使用VirtualizingStackPanel
。因此,尚未创建加载窗口时不在屏幕上的项目。将它们设置为Collapsed
后,一旦它们重新出现在屏幕上就无效。
您可以通过更改Window
的初始高度来解决这个问题。如果将其设置为550左右,则按预期工作。如果将其设置为150左右,则仍会看到很多元素。
如果你不想拥有那么多元素,你可以做的一件事就是改变ItemsPanel
。
答案 1 :(得分:4)
您可能需要disable virtualization。在需要之前,默认情况下不会创建ListBoxItems。当您折叠可见的ListBoxItems时,您可以腾出更多空间,这将在您的代码运行后创建。
将此添加到ListBox:
VirtualizingStackPanel.IsVirtualizing="False"
或者您可以使用样式来折叠项目,如下所示:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger >
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>