2012-08-15 12 views
10

Ich habe ein seltsames Verhalten mit VirtualizingStackPanel. Ich habe eine Liste mit Artikeln, die TextBlock mit TextWrap="Wrap" enthält. Hier ist der Code:VirtualizingStackPanel und TextWrapping Fehler? 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> 

Es funktioniert ziemlich gut, aber wenn ich versuche, sehr schnell blättern (mit der Maus auf Emulator, nicht prommatically) gibt es einige in scroll hinken, wahrscheinlich HorizontallOffset berechnet manchmal falsch, und in der unten endet mit sehr seltsamen Ergebnis (siehe Bild, rechtes Bild zeigt normales Verhalten).

scroll bug

Nach Forschung dachte ich VirtualizingStackPanel dieses Problem in Kombination und TextBlock.TextWrap="Wrap", wenn ich von diesem Paar ein Element entfernen Sie alle korrekt funktioniert.

Aber ich brauche Virtualisierung wegen großer Artikel zählen, und TextWrap für die korrekte Textanzeige.

Also denke ich darüber nach, meine eigene Implementierung des Virtualisierungspanels zu machen, kannst du mir bitte zeigen, wie man das macht oder wie man das aktuelle Problem löst?

UPD: Das Problem: (!)
auf den ersten beiden Bilder ListBox ist bereits gescrollt zum Boden (es nicht mehr nach unten gescrollt werden kann), sondern Elemente falsch platziert, korrekte Platzierung auf der rechten Seite Bild. Dies passiert nur, wenn Sie sehr schnell scrollen.

UPD2: Danke an Milan Aggarwal. Er lieferte einen guten Fall meines Problems here. Scheint wirklich ein Bug in ListBox zu sein. Problemumgehung, die zur Verfügung gestellt wird, passt nicht in mein Szenario, weil ich mit Steuerelementen innerhalb ListBox Element interagieren muss. Jetzt versuche ich ManipulationCompleted Ereignis zu fangen und überprüfen, ob es Inertial ist, wenn so scroll das bedeutet und ich auf Seite konzentrieren:

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

P. S. danke für viel Glück wünscht;)

+4

OFF_TOPIC: Viel Glück im VK Wettbewerb =) –

Antwort

1

Was ist das Problem auf dem 2. Bildschirm? Du meinst einen großen leeren Platz nach der letzten Nachricht? Die letzte Nachricht wird nicht am Ende der Seite angezeigt? Verstehe ich das richtig?

Eigentlich versuche ich nicht Ihren Code und Fehler zu reproduzieren, aber mein Punkt ist, dass, da Sie 3rd-Party-Libs (Silverlight Toolkit) in Ihrer Anwendung verwenden, warum nicht Coding4Fun Tools als auch zu benutzen?

ich diese Dummy-Klasse schrieb:

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; 
    } 
} 

Dann i in Hauptseite Konstruktor diesen Dummy-Code setzen:

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; 

Und in XAML habe ich eine Listbox mit Chat-Blase Kontrolle Toolkit:

<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> 

Ich lief es und sah keine seltsamen Verhaltensweisen, vielleicht ein bisschen Nacheilen. Es ist das Ergebnis:

dat pic is huge

Hoffnung ich Hilfe tat.


Spaß mit dem Wettbewerb, würde ich selbst teilnehmen, aber glaube nicht, dass in der Lage sein wird, einen anständigen Client für 1,5 Monate zu machen.

+0

Dank, ich werde dies überprüfen.nice Beispieltext :) – Alexander

+0

nein, dieses Steuerelement haben auch dieses Problem, nur mit unterschiedlicher Höhe und platzieren Sie in ihnen Schaltfläche zum Beispiel, klicken Sie auf eine beliebige Schaltfläche und scrollen, wird dies den Fehler reproduzieren – Alexander

+0

Ich habe gerade daran erinnert, dass ich angetroffen habe Dieses Problem bei meinem letzten Projekt und ich habe keinen Zweifel, es existiert in meinem aktuellen. Aber die Bedingungen, unter denen dieser Fehler auftritt (schnelles Scrollen), sind für mich nicht normal, also habe ich nicht versucht, das Problem zu beheben. =) – Oleg

9

Inorder das schwarze Auftreten zu überwinden beim Scrollen Sie Ihre Scroll-Steuerung virtualisieren benötigen. Für das sollte man IList erbt ein und Collection eigene ähnlich wie ObservableCollection erstellen, in dem Sie den Standard-Indexer auf Ihrer Caching Anforderung abhängig werden außer Kraft zu setzen und gleichzeitig einen Cache für Ihre Artikel zu erhalten. Ich finde, dass das sein könnte, was Sie suchen: http://blogs.msdn.com/b/ptorr/archive/2010/08/16/virtualizing-data-in-windows-phone-7-silverlight-applications.aspx

Es gibt ein Beispielprojekt auf dieser Seite. Versuchen Sie das mal aus.

Ich glaube auch, dass Sie dieses Problem http://blog.rsuter.com/?p=258 konfrontiert sind. Ich denke, das die Virtualisierung selbst mit gelöst werden. Hoffe, es

+0

danke, du antwortest mir in richtiger Richtung – Alexander

1

hilft Was ist das Problem bei dem zweiten Bild? Ist es, dass die BlackArea überhaupt auftauchten, oder ist es, dass die Scroll nicht „Stehaufmännchen“ nach dem Scrollen in den schwarzen Bereich zu füllen, mit Inhalt zu Ende?

Es ist wichtig zu wissen, weil ... dieser Effekt auf WPF/WP7 einfach natürlich ist .. BTW. das Stellrad sollte „Stehaufmännchen“ nach den über Scrollen, aber es scheint, es hat einen Fehler und manchmal vergisst, es zu tun.

Ich frage, weil schwarz/weiße Flächen oft nicht nur auf WP7 sind, aber und überall, wo es eine XAMLish Scroll mit Inertial Scrolling. Sie sehen, wenn schneller als die Plattform Scrollen neue Objekte zur Verfügung stellen kann, blättern Sie einfach außerhalb der vorher berechneten Elemente und sobald Sie „über“ sehr weit bewegen, die langsam ankommende Gegenstände plötzlich entdecken, dass es keine weiteren Elemente sind daher - zurück leerer Bereich ..

Dies geschieht meist, wenn einige Bedingungen auf einmal passieren: Sie blättern schnell (yay), sind Ihre Bindungen langsam (zu kompliziert Ausdrücke), Ihr Template-Rendering langsam (komplexe nicht wiederverwendbare UI-Vorlagen) ist , die Bindungen nicht wissen, wie viele Artikel gibt es (gebunden an IEnumerable nicht IList -> keine .Count Informationen) oder der Renderer doesnt wissen, wie viel Höhe für einen Artikel zu reservieren (der Artikel ist nicht konstante Höhe, aber eveyr Artikel muss berechnet seine eigene genaue Höhe) zu bestimmen.

Wenn Sie es korrigieren möchten, müssen Sie mit den Ursachen bekämpfen ersten oder müssen Sie Ihre eigene Scrolling implementieren oder Hack in Stapelplatte virtualisieren und die Zuführung von Gegenständen aus Binding mit dem Scrollen synchronisieren die scroller erraten die Gesamthöhe zu lassen besser: zum Beispiel Anzeige nur ein kleine auf einmal rein hört Ereignisse zu scrollen und hinzufügen/entfernen dynamisch nächste Packung von Artikeln aus Kopf/Schwanz der Liste .. Dies löst damit das Problem nicht schnell scrollen :)))))

ich glaube, dass das Element Höhe beschränke der einfachste Weg ist. Können Sie klug tun etwas nicht die Elemente tatsächlich konstant große zu machen?

+0

nein, Gegenstände müssen unterschiedlich hoch sein, sie müssen ihren ganzen Inhalt anzeigen. Milan Aggarwal posted eine gute Verbindung mit der Demonstration des Problems – Alexander

+0

Ich verstehe das und ich habe ziemlich viele Apps mit dem gleichen Problem. Wirklich, du musst dich auf die paar Dinge konzentrieren, auf die ich hingewiesen habe. Einige Kombinationen zwingen dann einfach einen solchen Effekt. Eine andere Sache, können Sie versuchen, "Trägheits-Scrolling" deaktivieren und verlassen Sie die normale, flache Scrolling, aber das ist in der Regel auch ungünstig, da dies das "Gefühl" senkt .. Ich kann Ihnen weiter helfen, ohne Ihren genauen Fall zu sehen. Ich kann nur auf die gemeinsamen Ursachen hinweisen. Das Problem selbst betrifft die Leistung von Code, Bindungen und Rendering. – quetzalcoatl

1

Ich schlage vor, Sie eine möglichst einfache Funktion erstellen, die für die eingewickelt TextBlock- und binden an, dass eine Höhe berechnet. Auf diese Weise Sie den Vorteil variabler Höhe Elemente in der List-Box, aber mit dem virtualisieren Stapelplatte zu halten bekommen.