Я создаю приложение чата с ListView, содержащим сообщения. Когда новое сообщение отправлено / получено, ListView должен прокрутить до нового сообщения.
Я использую MVVM, поэтому ListView выглядит как
<ScrollViewer>
<ItemsControl Source="{Binding Messages}" />
</ScrollViewer>
Как я могу это сделать?
РЕДАКТИРОВАТЬ: Я пытался сделать эту работу в версиях до Anniversary Update, создающих поведение. Вот что у меня есть на данный момент:
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);
}
}
}
В коде используются VisualTreeExtensions из набора инструментов сообщества UWP.
Однако позиция после вызова TransformPoint всегда возвращает {0, 0}
Что я делаю неправильно?
ListView
вScrollViewer
, он прокручивается автоматически. Чтобы получить доступ к его внутреннемуScrollViewer
(например, чтобы вызвать его методChangeView
для прокрутки до заданного смещения пикселей), используйтеListView.GetScrollViewer()
. - person andreask   schedule 04.05.2017