how to make scroll rule always at end of the ListView automatic without focus in WPF?
The answers from @pduncan and @MattBurland both have some problems, primarily that they fail to unregister the behaviour properly.
This implementation stores the handler in another attached property so that you can toggle the behaviour on and off, perhaps through a binding.
Note that this applies to ListView
. If you are using ListBox
, change occurrences of ListView
to ListBox
.
public static class ListViewExtensions
{
public static readonly DependencyProperty AutoScrollToEndProperty = DependencyProperty.RegisterAttached("AutoScrollToEnd", typeof(bool), typeof(ListViewExtensions), new UIPropertyMetadata(OnAutoScrollToEndChanged));
private static readonly DependencyProperty AutoScrollToEndHandlerProperty = DependencyProperty.RegisterAttached("AutoScrollToEndHandler", typeof(NotifyCollectionChangedEventHandler), typeof(ListViewExtensions));
public static bool GetAutoScrollToEnd(DependencyObject obj) => (bool)obj.GetValue(AutoScrollToEndProperty);
public static void SetAutoScrollToEnd(DependencyObject obj, bool value) => obj.SetValue(AutoScrollToEndProperty, value);
private static void OnAutoScrollToEndChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
var listView = s as ListView;
if (listView == null)
return;
var source = (INotifyCollectionChanged)listView.Items.SourceCollection;
if ((bool)e.NewValue)
{
NotifyCollectionChangedEventHandler scrollToEndHandler = delegate
{
if (listView.Items.Count <= 0)
return;
listView.Items.MoveCurrentToLast();
listView.ScrollIntoView(listView.Items.CurrentItem);
};
source.CollectionChanged += scrollToEndHandler;
listView.SetValue(AutoScrollToEndHandlerProperty, scrollToEndHandler);
}
else
{
var handler = (NotifyCollectionChangedEventHandler)listView.GetValue(AutoScrollToEndHandlerProperty);
source.CollectionChanged -= handler;
}
}
}
Use it like this:
<ListView local:ListViewExtensions.AutoScrollToEnd="{Binding Path=AutoScroll}">
I also made it a a static class, as you don't need to instantiate it (nor does it need to derive from DependencyObject
). The cast to INotifyCollectionChanged
was changed so that errors surface as cast exceptions, not NREs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With