Dans mon application, j'ai un ListBox
avec des éléments. L'application est écrite en WPF.
Comment faire défiler automatiquement jusqu'au dernier élément ajouté? Je souhaite que ScrollViewer
soit déplacé à la fin de la liste lorsqu'un nouvel élément a été ajouté.
Y a-t-il un événement comme ItemsChanged
? (Je ne veux pas utiliser l'événement SelectionChanged
)
Essaye ça:
lstBox.SelectedIndex = lstBox.Items.Count -1;
lstBox.ScrollIntoView(lstBox.SelectedItem) ;
Dans votre fenêtre principale, cela sélectionnera et se concentrera sur le dernier élément de la liste!
La façon la plus simple de procéder:
if (VisualTreeHelper.GetChildrenCount(listView) > 0)
{
Border border = (Border)VisualTreeHelper.GetChild(listView, 0);
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
scrollViewer.ScrollToBottom();
}
Il fonctionne toujours pour les contrôles ListView et ListBox. Attachez ce code au listView.Items.SourceCollection.CollectionChanged
event et vous avez un comportement de défilement automatique entièrement automatique.
Gardez à l'esprit que listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
ne fonctionne que si vous n'avez aucun élément en double. Si vous avez des éléments avec le même contenu, il défile jusqu'à la première recherche.
Voici la solution que j'ai trouvée:
ListBoxAutomationPeer svAutomation = (ListBoxAutomationPeer)ScrollViewerAutomationPeer.CreatePeerForElement(myListBox);
IScrollProvider scrollInterface = (IScrollProvider)svAutomation.GetPattern(PatternInterface.Scroll);
System.Windows.Automation.ScrollAmount scrollVertical = System.Windows.Automation.ScrollAmount.LargeIncrement;
System.Windows.Automation.ScrollAmount scrollHorizontal = System.Windows.Automation.ScrollAmount.NoAmount;
//If the vertical scroller is not available, the operation cannot be performed, which will raise an exception.
if ( scrollInterface.VerticallyScrollable )
scrollInterface.Scroll(scrollHorizontal, scrollVertical);
La meilleure solution consiste à utiliser l'objet ItemCollection dans le contrôle ListBox, cette collection a été spécialement conçue pour les utilisateurs de contenu. Il a une méthode prédéfinie pour sélectionner le dernier élément et conserver une référence de position du curseur ....
myListBox.Items.MoveCurrentToLast();
myListBox.ScrollIntoView(myListBox.Items.CurrentItem);
Une approche légèrement différente de celles présentées jusqu'à présent.
Vous pouvez utiliser l'événement ScrollViewer
ScrollChanged
et surveiller que le contenu de ScrollViewer
s'agrandit.
private void ListBox_OnLoaded(object sender, RoutedEventArgs e)
{
var listBox = (ListBox) sender;
var scrollViewer = FindScrollViewer(listBox);
if (scrollViewer != null)
{
scrollViewer.ScrollChanged += (o, args) =>
{
if (args.ExtentHeightChange > 0)
scrollViewer.ScrollToBottom();
};
}
}
Cela évite certains problèmes avec la liaison à la modification ListBox
ItemsSource
.
Le ScrollViewer
peut également être trouvé sans supposer que le ListBox
utilise le modèle de contrôle par défaut.
// Search for ScrollViewer, breadth-first
private static ScrollViewer FindScrollViewer(DependencyObject root)
{
var queue = new Queue<DependencyObject>(new[] {root});
do
{
var item = queue.Dequeue();
if (item is ScrollViewer)
return (ScrollViewer) item;
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
queue.Enqueue(VisualTreeHelper.GetChild(item, i));
} while (queue.Count > 0);
return null;
}
Attachez ensuite ceci à l'événement ListBox
Loaded
:
<ListBox Loaded="ListBox_OnLoaded" />
Cela pourrait être facilement modifié pour être une propriété attachée, pour le rendre plus général.
listBox.ScrollIntoView (listBox.Items [listBox.Items.Count - 1]);
Pour moi, la façon travail le plus simple était la suivante: (sans liaison)
private void WriteMessage(string message, Brush color, ListView lv)
{
Dispatcher.BeginInvoke(new Action(delegate
{
ListViewItem ls = new ListViewItem
{
Foreground = color,
Content = message
};
lv.Items.Add(ls);
lv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
}));
}
Vous n'avez pas besoin de créer de classes ou de changer le xaml, écrivez simplement les messages avec cette méthode et cela défile automatiquement.
Appeler juste
myLv.Items.Add(ls);
myLv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
par exemple, ne travaille pas pour moi.
Vous pouvez essayer la méthode ListBox.ScrollIntoView () , bien qu'il y ait des problèmes dans certains cas ...
Voici un exemple de Tamir Khason: ListBox de défilement automatique dans WPF