Xamarin Forms 4.4中UWP平台ItemsUpdatingScrollMode失效的替代方案咨询
Hey there, I’ve dealt with this exact frustration in Xamarin.Forms 4.4 on UWP before—turns out the ItemsUpdatingScrollMode="KeepLastItemInView" just doesn’t play nice with UWP yet. But don’t worry, there’s a solid custom renderer workaround that works like a charm until Microsoft rolls out official support.
Here’s how to set it up:
1. Create a custom ListView in your shared project
First, we’ll make a subclass of ListView to add a bindable property for controlling the auto-scroll behavior:
using Xamarin.Forms; namespace YourAppName { public class AutoScrollListView : ListView { public static readonly BindableProperty AutoScrollToLastProperty = BindableProperty.Create( nameof(AutoScrollToLast), typeof(bool), typeof(AutoScrollListView), defaultValue: false); public bool AutoScrollToLast { get => (bool)GetValue(AutoScrollToLastProperty); set => SetValue(AutoScrollToLastProperty, value); } } }
2. Build the UWP custom renderer
Next, we’ll create a renderer for UWP that hooks into the native ListView’s events to handle scrolling:
using Windows.UI.Xaml.Controls; using YourAppName; using YourAppName.UWP; using Xamarin.Forms; using Xamarin.Forms.Platform.UWP; using System.Threading.Tasks; [assembly: ExportRenderer(typeof(AutoScrollListView), typeof(AutoScrollListViewRenderer))] namespace YourAppName.UWP { public class AutoScrollListViewRenderer : ListViewRenderer { protected override void OnElementChanged(ElementChangedEventArgs<ListView> e) { base.OnElementChanged(e); if (Control is ListViewBase nativeListView && Element is AutoScrollListView autoScrollListView) { // Listen for changes to the items collection nativeListView.Items.VectorChanged += (sender, args) => { TriggerAutoScroll(nativeListView, autoScrollListView); }; // Scroll to last item when the list finishes loading nativeListView.Loaded += (sender, args) => { TriggerAutoScroll(nativeListView, autoScrollListView); }; } } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == AutoScrollListView.AutoScrollToLastProperty.PropertyName) { if (Control is ListViewBase nativeListView && Element is AutoScrollListView autoScrollListView) { TriggerAutoScroll(nativeListView, autoScrollListView); } } } private void TriggerAutoScroll(ListViewBase nativeListView, AutoScrollListView autoScrollListView) { if (autoScrollListView.AutoScrollToLast && nativeListView.Items.Count > 0) { // Add a small delay to handle bulk updates (prevents jitter) Task.Delay(50).ContinueWith(_ => { Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync( Windows.UI.Core.CoreDispatcherPriority.Normal, () => nativeListView.ScrollIntoView(nativeListView.Items[nativeListView.Items.Count - 1], ScrollIntoViewAlignment.Default)); }); } } } }
3. Use the custom ListView in your XAML
Replace your regular ListView with our custom AutoScrollListView and set AutoScrollToLast="True":
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:YourAppName" x:Class="YourAppName.YourPage"> <local:AutoScrollListView ItemsSource="{Binding YourItemCollection}" AutoScrollToLast="True"> <!-- Your ItemTemplate and other layout settings here --> </local:AutoScrollListView> </ContentPage>
A quick note on performance:
The small Task.Delay(50) in the renderer helps prevent jitter if you’re adding multiple items at once. If you’re only adding single items occasionally, you can remove the delay to make the scroll instant.
This workaround has been reliable in several projects I’ve worked on—it mimics the exact behavior you’d expect from KeepLastItemInView without relying on the broken UWP platform support.
内容的提问来源于stack exchange,提问作者Esteban Chornet

