2010-08-06 6 views
6

Estoy intentando crear una lista de desplazamiento de bloques de texto bastante grandes. Quiero que haya una barra de desplazamiento vertical para mostrarlos todos, y si se desbordan de un cierto tamaño, quiero que muestren puntos suspensivos. De hecho, tengo todo esto funcionando bastante bien.Obtención de la virtualización de la interfaz de usuario trabajando con ItemsControl en Silverlight

Tengo el siguiente XAML de Silverlight:

<Grid x:Name="LayoutRoot" MaxWidth="500" MinWidth="100" 
    MaxHeight="500" MinHeight="100"> 
    <Grid.DataContext> 
     <app:MainPageViewModel/> 
    </Grid.DataContext> 
    <ScrollViewer> 
    <ItemsControl ItemsSource="{Binding TextItems}" Margin="0,20,0,20"> 
     <ItemsControl.ItemTemplate><DataTemplate> 
      <Border MaxHeight="175" Margin="0,0,0,18" CornerRadius="5"> 
       <TextBlock Margin="2" TextTrimming="WordEllipsis" 
        TextWrapping="Wrap" Text="{Binding}"/> 
      </Border> 
     </DataTemplate></ItemsControl.ItemTemplate> 
    </ItemsControl> 
    </ScrollViewer> 
</Grid> 

Mi problema es que este diseño no utiliza la virtualización de la interfaz de usuario, como por ejemplo con un VirtualizingStackPanel. Entonces es bastante lento ¿Cuál es la mejor manera de obtener la virtualización de la interfaz de usuario en este diseño? He intentado alrededor de media docena de maneras diferentes y nada ha funcionado muy bien.

Me las arreglé para hacer que esto funcione en un ListBox porque parece ser compatible con la virtualización desde el primer momento. Sin embargo, preferiría usar ItemsControl ya que no quiero que estas cosas sean seleccionables, y no quiero el estilo que viene con un ListBox.

Esto a Silverlight 4.

Respuesta

15

Hay algunas cosas que hay que hacer para que esto funcione.

  1. Establecer la ItemsPanelTemplate para su ItemsControl a un VirtualizingStackPanel.
  2. Incorpore el ScrollViewer dentro de ControlTemplate para su ItemsControl en lugar de solo envolviéndolo por fuera.
  3. Asegúrese de que ItemsControl tenga una altura fija para que el sistema de diseño pueda calcular cuántos elementos necesita para llenar la ventana gráfica. (Parece que ya está haciendo esto poniendo ItemsControl en una cuadrícula - que permitirá el sistema de diseño para determinar la altura asignado para el control)

Aquí está el ejemplo más simple que podría llegar a de este trabajo :

<ItemsControl ItemsSource="{Binding TextItems}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <VirtualizingStackPanel /> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.Template> 
      <ControlTemplate TargetType="ItemsControl"> 
       <Border> 
        <ScrollViewer> 
         <ItemsPresenter/> 
        </ScrollViewer> 
       </Border> 
      </ControlTemplate> 
     </ItemsControl.Template> 
    </ItemsControl> 
+0

Eso funcionó como un encanto Steve. Entonces, la diferencia principal entre su solución y lo que estaba tratando de hacer es que utilizó ItemsControl.Template para agregarlo en el ScrollViewer, mientras que yo solo estaba tratando de colocar un ScrollViewer fuera del control. ¿Puedes explicar por qué tuyo funciona y lo que yo estaba tratando de hacer no? Puede ayudarme a entender la solución un poco mejor. – RationalGeek

+1

Genial, me alegro de que funcionó para ti. Básicamente, lo que sucede es que si coloca un ScrollViewer alrededor de la parte exterior de ItemsControl, el motor de diseño representará todo el ItemsControl; generará contenedores de elementos para todos los elementos del control. ScrollViewer solo limita la vista a una pequeña parte de ItemsControl, pero todo el ItemsControl con todos los elementos existe en la memoria. La segunda forma, al colocar el ScrollViewer dentro de la plantilla, le da a ItemsControl la capacidad de limitar la cantidad de contenedores de elementos que crea; solo creará lo suficiente para llenar el espacio disponible. –

+0

tiene sentido. ¡Gracias de nuevo! – RationalGeek

Cuestiones relacionadas