我想使用 CollectionView 创建一个日志窗口。每当添加新项目时,它应该自动滚动到底部。我尝试使用“行为”来实现此功能,以实现轻松的代码可移植性。这是我如何编写该行为的:
namespace Behaviors;
public class ScrollToBottomBehavior
{
public static readonly BindableProperty DataSourceProperty =
BindableProperty.CreateAttached("DataSource",
typeof(object),
typeof(ScrollToBottomBehavior),
null,
BindingMode.TwoWay,
propertyChanged: OnDataSourceChanged);
public static int GetDataSource(BindableObject view) => (int)view.GetValue(DataSourceProperty);
public static void SetDataSource(BindableObject view, int value) => view.SetValue(DataSourceProperty, value);
private static void OnDataSourceChanged(BindableObject sender, object oldValue, object newValue)
{
if (sender is not CollectionView view) return;
//ObservableCollection<object> collection = newValue as ObservableCollection<object>;
if (newValue is not ObservableCollection<object> collection) return;
//view?.ScrollTo(collection.LastOrDefault(), null, ScrollToPosition.End);
view?.ScrollTo(collection.Count - 1, position: ScrollToPosition.End);
}
}
但是,我失败了,因为ObservableCollection
的Add方法没有触发PropertyChanged事件。 我还尝试在每次添加项目时手动将
SelectedItem设置为 ObservableCollection 的最后一项,但这并没有使 CollectionView 自动滚动到底部。 我有几个想法:
修改
internal class CollectionViewExtended : CollectionView
{
public static readonly BindableProperty ScrollToButtomProperty =
BindableProperty.Create(nameof(ScrollToButtom), typeof(bool), typeof(CollectionViewExtended), false);
public bool ScrollToButtom
{
get => (bool)GetValue(ScrollToButtomProperty);
set => SetValue(ScrollToButtomProperty, value);
}
protected override void OnChildAdded(Element child)
{
base.OnChildAdded(child);
if (ScrollToButtom)
{
ScrollTo(child, position: ScrollToPosition.End, animate: true);
}
}
}
如有任何建议,我们将不胜感激。
CollectionView
定义了
ItemsUpdatingScrollMode
属性,该属性由可绑定属性支持。此属性获取或设置一个 ItemsUpdatingScrollMode
枚举值,该值表示向其中添加新项目时 CollectionView
的滚动行为。 ItemsUpdatingScrollMode
枚举定义了以下成员:
KeepItemsInView
KeepScrollOffset
KeepLastItemInView
ItemsUpdatingScrollMode
属性的默认值为
KeepItemsInView
。因此,当新项目添加到 CollectionView 时,列表中的第一项将保持显示。要确保添加新项目时显示列表中的最后一项,请将 ItemsUpdatingScrollMode
属性设置为 KeepLastItemInView
:<CollectionView ItemsUpdatingScrollMode="KeepLastItemInView">
...
</CollectionView>
有关更多信息,请查看文档:添加新项目时控制滚动位置注:
事实上,滚动完成后项目的确切位置可以使用
ScrollTo
方法的位置参数来指定。此参数接受
ScrollToPosition
枚举成员。更多信息请查看文档:控制滚动位置