2012-08-15 12 views
10

Tengo un comportamiento extraño con VirtualizingStackPanel. Tengo una lista con los artículos que contiene TextBlock con TextWrap="Wrap". Aquí está el código:¿Error de VirtualizingStackPanel y TextWrapping? Windows Phone

<ListBox x:Name="messagesList" ItemsSource="{Binding Messages}" > 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 
     </Style> 
    </ListBox.ItemContainerStyle> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <toolkit:ContextMenuService.ContextMenu> 
        <toolkit:ContextMenu> 
        ... 
        </toolkit:ContextMenu> 
       </toolkit:ContextMenuService.ContextMenu> 
       <CheckBox Style="{Binding Own, Converter={StaticResource MsgTypeToStyle}}" 
          Tag="{Binding TimeString}" 
          IsEnabled="True"> 
        <TextBlock Text="{Binding Content}" TextWrapping="Wrap"/> 
       </CheckBox> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Funciona bastante bien, pero si trato de desplazarse muy rápido (a través del ratón en el emulador, no prommatically) hay algo de retraso en el desplazamiento, probablemente HorizontallOffset veces calcula mal, y en el abajo en los extremos con resultados muy extraños (ver imagen, la imagen de la derecha demuestra un comportamiento normal).

scroll bug

Después de la investigación me di cuenta de que el problema en combinación VirtualizingStackPanel y TextBlock.TextWrap="Wrap", si quito uno de los elementos de esta pareja todo funciona correctamente.

Pero necesito virtualización debido a la cantidad de elementos grandes y TextWrap para la visualización correcta del texto.

Así que pienso en hacer mi propia implementación de Virtualizing Panel, ¿pueden guiarme, cómo hacerlo o cómo solucionar el problema actual?

UPD: El problema: (!)
en las dos primeras imágenes ListBox ya está desplazado a la parte inferior (no se puede desplazar hacia abajo más), pero los elementos coloca de forma incorrecta, correcta colocación muestra a la derecha imagen. Esto sucede solo si se desplaza muy rápido.

UPD2: Gracias a Milan Aggarwal. Proporcionó un buen caso de mi problema here. Parece que es realmente un error en ListBox. Solución alternativa, siempre que no se ajuste a mi escenario, porque necesito interactuar con los controles dentro del elemento ListBox. Ahora estoy tratando de recuperar ManipulationCompleted evento y comprobar si es Inertial, si por lo que significa de desplazamiento y ajustar el enfoque a la página:

void messagesList_ManipulationCompleted(object sender, ManipulationCompletedEventArgs e) 
    { 
     if (e.IsInertial) 
      this.Focus(); 
    } 

P. S. gracias por deseos de buena suerte;)

+4

OFF_TOPIC: Buena suerte en el concurso de VK =) –

Respuesta

1

¿Cuál es el problema en la 2da pantalla? ¿Te refieres a un gran espacio vacío después del último mensaje? ¿El último mensaje no está en la parte inferior de la página? ¿Estoy obteniendo esto bien?

En realidad yo no trato de reproducir su código y error, pero mi punto es que dado que está utilizando bibliotecas 3 ª parte (juego de herramientas) en su aplicación, ¿por qué no usar Coding4Fun Tools así?

escribí esta clase ficticia:

public class Message 
{ 
    public string Time { get; private set; } 
    public string Content { get; private set; } 

    public Message(string time, string content) 
    { 
     Time = time; 
     Content = content; 
    } 
} 

entonces puse este código ficticio en la página principal constructor:

var _messages = new ObservableCollection<Message>(); 

for (int i = 0; i < 50; i++) 
{ 
    _messages.Add(new Message("12:40", "Teh very long string which should be wrapped. Pavel Durov gives WP7 Contest winners less money than he did for Android/iOS winners. FFFUUUUUUUUUUUUUU ")); 
} 

this.ListBox.ItemsSource = _messages; 

Y en xaml pongo un cuadro de lista con el chat de control de la burbuja de juego de herramientas:

<ListBox x:Name="ListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <c4fToolkit:ChatBubble> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition Height="Auto"/> 
        </Grid.RowDefinitions> 
        <TextBlock Grid.Row="0" 
           Text="{Binding Content}" 
           TextWrapping="Wrap"/> 
        <TextBlock Grid.Row="1" 
           Text="{Binding Time}" 
           HorizontalAlignment="Right"/> 
       </Grid> 
      </c4fToolkit:ChatBubble> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Lo ejecuté y no vi comportamientos extraños, tal vez un poco de retraso. No es el resultado:

dat pic is huge

Espero haber hecho un poco de ayuda.


diversión con el concurso, que sería en sí participar, pero no creo que será capaz de hacer que un cliente decente durante 1,5 meses.

+0

gracias, voy a ver esto.texto de muestra agradable :) – Alexander

+0

no, este control también tiene este problema, simplemente haga elementos con diferente altura y coloque dentro de ellos botón, por ejemplo, haga clic en cualquier botón y desplazamiento, esto reproducirá el error – Alexander

+0

Acabo de recordar que me encontré este problema en mi último proyecto y no tengo dudas de que existe en mi actual. Pero las condiciones en las que aparece este error (desplazamiento rápido) no son normales para mí, así que no intenté arreglarlo. =) – Oleg

9

finde para superar la ocurrencia negro de desplazamiento que necesita para virtualizar el control de desplazamiento. Para que usted debe heredar IList y crear un Collection de su propia similar a ObservableCollection en el que tendrá que reemplazar el indexador por defecto en función de sus necesidades de almacenamiento en caché y al mismo tiempo mantener una caché para sus artículos. Siento que esto podría ser lo que buscas: http://blogs.msdn.com/b/ptorr/archive/2010/08/16/virtualizing-data-in-windows-phone-7-silverlight-applications.aspx

Hay un proyecto de ejemplo de esa página. Trate de eso.

También siento que se enfrentan a este problema http://blog.rsuter.com/?p=258. Supongo que esto se resolverá mediante la virtualización en sí. Espero que ayuda

+0

gracias, tu respuesta me señala en la dirección correcta – Alexander

1

¿Cuál es el problema en la segunda imagen? ¿Es que la BlackArea apareció en absoluto, o es que el ScrollView no "repunte" después de que el desplazamiento terminó de llenar el área de color negro con el contenido?

Es importante saber esto, porque ... este efecto es simplemente natural para WPF/WP7 .. Por cierto . el desplazador debe "repunte" después de que el exceso de desplazamiento, pero parece que tiene un error y, a veces se olvida de hacerlo.

Lo digo porque las zonas negras/blancas son muy a menudo no sólo en WP7, pero y en cualquier lugar donde hay una ScrollViewer XAMLish con desplazamiento inercial. Usted ve, cuando se desplaza más rápido que la plataforma puede proporcionar nuevos elementos, que acaba de desplazarse fuera de los puntos calculados de antemano y una vez que "sobre" desplazarse muy lejos, los artículos lentamente-entrantes repentinamente descubren que no hay más elementos, por lo tanto - volver área vacía ..

Esto sucede sobre todo cuando algunas condiciones ocurren a la vez: se desplaza rápido (yay), sus enlaces son lentos (expresiones excesivamente complicados), su plantilla-renderizado es lento (plantillas de interfaz de usuario complejas no reutilizables) , los enlaces no sabe cuántos elementos hay (obligados a IEnumerable no IList -> ninguna información .Count), o el imposible de render saber cuánto altura para reservar para un artículo (el artículo no está de altura constante, pero eveyr artículo tiene que ser calculada para determinar su propia altura exacta).

Si desea corregirlo, debe luchar con esas causas primer o debe implementar su propio desplazamiento o piratear la virtualización de panel de pila y sincronizar la alimentación de artículos de BindingSource con el movimiento en sentido vertical para permitir que el desplazador supongo que la altura total mejor: por ejemplo, mostrar sólo una pequeña elementos a la vez, escuchar desplazamiento eventos y añadir/eliminar próximo paquete de artículos de la cabeza/cola de la lista de forma dinámica .. Esto va a resolver el problema al no permitir que desplazarse rápido :)))))

creo que limitar la altura artículo es la forma más fácil. ¿No puedes hacer algo inteligente como para hacer que los elementos de hecho constante de tamaño?

+0

no, los artículos deben ser de diferente altura, deben mostrar todo su contenido. Milan Aggarwal publicó un gran enlace con la demostración del problema – Alexander

+0

Lo entiendo y tengo bastantes aplicaciones con el mismo problema. Realmente, debes enfocarte en las pocas cosas que he señalado. Algunas combinaciones de entonces simplemente fuerzan tal efecto. Otra cosa es intentar deshabilitar el "desplazamiento de inercia" y dejar el desplazamiento normal, de desplazamiento plano, pero eso generalmente también es desfavorable, ya que esto reduce la "sensación". No puedo ayudarte más sin ver tu caso exacto. Solo puedo señalar las causas comunes. El problema es sobre el rendimiento de su código, enlaces y representación. – quetzalcoatl

1

Sugiero crear la función más simple posible que calcula una altura para el bloque de texto envuelto y se unen a eso. De esta manera, se obtiene el beneficio de elementos variables de altura en el cuadro de lista, pero tiene que mantener con el panel de la virtualización de pila.