2011-05-25 28 views
6

Si hago clic en un elemento en el medio de la lista, espero que todos los elementos excepto uno se colapsen. El resultado real es que quedan muchos elementos. ¿Por qué? Este es el programa completo.¿Por qué no se colapsan mis listboxitems?

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> 

Respuesta

7

creo que es debido a su uso de ItemContainerGenerator.ContainerFromItem.

El ListBox está usando un VirtualizingStackPanel de forma predeterminada. Por lo tanto, los elementos que no están en la pantalla cuando carga la ventana aún no se han creado. Establecerlos en Collapsed no tiene ningún efecto una vez que se vuelven a mostrar en la pantalla.

Puede cambiar esto un poco cambiando la altura inicial del Window. Si lo configura en 550 o así, funciona como se esperaba. Si lo configura en 150 o así, tendrá MUCHOS elementos aún visibles.

Una cosa que puedes hacer para cambiar esto si no vas a tener tantos elementos es simplemente cambiar el ItemsPanel.

+0

Gran respuesta gracias. – 0x4f3759df

4

es probable que tenga a disable virtualization. ListBoxItems no se creará de manera predeterminada, hasta que sea necesario. Cuando contrae los ListBoxItems visibles, deja espacio para más, que se crearán después de que se ejecute su código.

Agregar a su ListBox:

VirtualizingStackPanel.IsVirtualizing="False" 

O Probablemente se podría utilizar un estilo de colapsar los artículos de esta manera:

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

Intenté usar esos desencadenantes el otro día y el rendimiento fue miserable ... como un retraso de 5 segundos cuando mi expectativa era un rendimiento de segundo. – 0x4f3759df

+0

Gracias por su respuesta – 0x4f3759df

+0

@iterationx - Entonces, ¿la lista solo contiene 30 elementos y le lleva 5 segundos ocultar los elementos con el Estilo? – CodeNaked

Cuestiones relacionadas