J'utilise un Winforms ListBox comme une petite liste d'événements, et je veux le remplir pour que le dernier événement (en bas) soit visible. SelectionMode
est défini sur aucun. L'utilisateur peut faire défiler la liste, mais je préférerais qu'il commence par défiler jusqu'à la fin.
En regardant le manque de support pour des choses comme ScrollIntoView
, EnsureVisible
, je suppose que je devrai créer un contrôle personnalisé qui hérite de ListBox; mais je ne sais pas quoi faire à partir de là.
Quelques pointeurs?
Je pense que vous pouvez le faire facilement en définissant la propriété TopIndex
de manière appropriée.
Par exemple:
int visibleItems = listBox.ClientSize.Height / listBox.ItemHeight;
listBox.TopIndex = Math.Max(listBox.Items.Count - visibleItems + 1, 0);
Faites défiler vers le bas:
listbox.TopIndex = listbox.Items.Count - 1;
Faites défiler vers le bas et sélectionnez le dernier élément:
listbox.SelectedIndex = listbox.Items.Count - 1;
C'est ce que j'ai fini avec WPF (.Net Framework 4.6.1):
Scroll.ToBottom(listBox);
Utilisation de la classe d'utilitaires suivante:
public partial class Scroll
{
private static ScrollViewer FindViewer(DependencyObject root)
{
var queue = new Queue<DependencyObject>(new[] { root });
do
{
var item = queue.Dequeue();
if (item is ScrollViewer) { return (ScrollViewer)item; }
var count = VisualTreeHelper.GetChildrenCount(item);
for (var i = 0; i < count; i++) { queue.Enqueue(VisualTreeHelper.GetChild(item, i)); }
} while (queue.Count > 0);
return null;
}
public static void ToBottom(ListBox listBox)
{
var scrollViewer = FindViewer(listBox);
if (scrollViewer != null)
{
scrollViewer.ScrollChanged += (o, args) =>
{
if (args.ExtentHeightChange > 0) { scrollViewer.ScrollToBottom(); }
};
}
}
}