I'm creating a chat application with a ListView that contains the messages. When a new message is sent/received, the ListView should scroll to the new message.
I'm using MVVM, so the ListView looks like
<ScrollViewer>
<ItemsControl Source="{Binding Messages}" />
</ScrollViewer>
How can I do it?
EDIT: I tried to make this work in versions prior to the Anniversary Update creating a Behavior. This is what I have so far:
public class FocusLastBehavior : Behavior<ItemsControl>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Items.VectorChanged += ItemsOnVectorChanged;
}
private void ItemsOnVectorChanged(IObservableVector<object> sender, IVectorChangedEventArgs @event)
{
var scroll = VisualTreeExtensions.FindVisualAscendant<ScrollViewer>(AssociatedObject);
if (scroll == null)
{
return;
}
var last = AssociatedObject.Items.LastOrDefault();
if (last == null)
{
return;
}
var container = AssociatedObject.ContainerFromItem(last);
ScrollToElement(scroll, (UIElement)container);
}
private static void ScrollToElement(ScrollViewer scrollViewer, UIElement element,
bool isVerticalScrolling = true, bool smoothScrolling = true, float? zoomFactor = null)
{
var transform = element.TransformToVisual((UIElement)scrollViewer.Content);
var position = transform.TransformPoint(new Point(0, 0));
if (isVerticalScrolling)
{
scrollViewer.ChangeView(null, position.Y, zoomFactor, !smoothScrolling);
}
else
{
scrollViewer.ChangeView(position.X, null, zoomFactor, !smoothScrolling);
}
}
}
The code uses VisualTreeExtensions from the UWP Community Toolkit
However, the position after the call to TransformPoint always returns {0, 0}
What am I doing wrong?