Ich muss wissen, wenn eine ListBox
das Rendern zum ersten Mal beendet hat, so dass ich es nach oben scrollen kann, um den Benutzer mit dem ersten Element in der Liste zu präsentieren.Woher weiß ich, wann eine ListBox in Silverlight gerendert wurde?
Ich habe ein ListBox
die RichTextBox
verwendet darin DataTemplate
ist:
<DataTemplate x:Key="HelpTextTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
...
<ContentControl>
...
<RichTextBox x:Name="HelpTextContent" Grid.Row="1"
Tag="{Binding Path=HelpObject.Text, Mode=TwoWay}"
TextWrapping="Wrap"
HorizontalAlignment="Stretch"
Margin="0,0,20,0"
Loaded="RichTextBox_Loaded"
ContentChanged="RichTextBox_ContentChanged"
SelectionChanged="RichTextBox_SelectionChanged"/>
...
</ContentControl>
...
</Grid>
</DataTemplate>
Die ListBox
an einen ObservableCollection
gebunden ist.
hatte ich ein Problem mit dem Scrollen der ListBox
- wenn Höhe der RichTextBox
größer war als der die ListBox
der Benutzer nicht auf den Boden der RichTextBox
bewegen kann. Die ListBox
würde zum nächsten Element in der Liste springen. Die Höhe des Schiebereglers der Bildlaufleiste würde sich ebenfalls ändern. Dies liegt daran, dass die tatsächliche Höhe der RichTextBox
nur berechnet wird, wenn sie tatsächlich gerendert wird. Wenn es nicht auf dem Bildschirm angezeigt wird, wird die Höhe auf einen kleineren Wert zurückgesetzt (ich denke, der Code geht davon aus, dass der Text in eine einzige Zeile passt und nicht umbrochen werden muss).
Ich verfolgt diese Probleme bis zur ListBox
Verwendung eines VirtualisingStackPanel
, um die Elemente zu zeichnen. Als ich das mit einem einfachen StackPanel
ersetzte, gingen diese Probleme weg.
Dies erstellt dann das Problem, das ich jetzt habe, das ist, dass die ListBox
scrollt an den unteren Rand der Liste bei der ersten Belastung. Die Ereignisse Loaded
und LayoutUpdated
auf der ListBox
auftreten, bevor die Daten geladen wurden. Ich habe versucht, für das PropertyChanged
Ereignis auf dem View-Modell zu hören, wenn die ObservableCollection
initialisiert:
void editViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "ListDataSource":
// Try to scroll to the top of the ListBox
break;
}
}
dies auch zu früh ausgelöst wird. Die Liste wird gerendert nach Dieses Ereignis wird ausgelöst und bewirkt, dass die ListBox
nach unten scrollt.
Hmm. Ich bin vorsichtig bei solchen Dingen - vor allem, weil es eine Menge Dinge in der Liste geben könnte - aber ich werde es versuchen. – ChrisF
Da das Rendering im UI-Thread stattfindet und Dispatcher.BeginInvoke den Scrollvorgang an die Warteschlange des UI-Threads weiterleitet, spielt es eigentlich keine Rolle, wie groß Ihre Liste ist. Scrollen sollte durchgeführt werden, nachdem andere aktuelle UI-Thread-Anweisungen ausgeführt wurden. Natürlich, wenn Ihre Sammlung (oder andere Teile der Kontrolle/Vorlage) async erstellt wird - es funktioniert nicht.Aber es ist ein anderer Fall .. Normalerweise für einfache Szenarien funktioniert es. – Kreol
Guter Punkt dort - obwohl die Liste asynchron bevölkert ist .... – ChrisF