Xamarin 窗体中的自动滚动列表视图问题

problem with autoscroll listview in xamarin forms

提问人:Yoandry Castellanos 提问时间:11/1/2023 更新时间:11/2/2023 访问量:77

问:

我需要我的列表视图在添加元素时执行自动滚动,为此,我实现了一个继承自 listview 的类,它可以工作,但它有一个弱点,当您添加相等的元素时,它会滚动到第一个可见的元素,让我解释一下最好添加几个元素

  1. C#
  2. [HTML全文]
  3. T-SQL
  4. PL-SQL
  5. PL-SQL

在这里,它不是滚动到最后一个 PL-SQL,而是停留在第一个 PL-SQL 上,它向我展示了滚动的动画,但我添加的第一个 PL-SQL 仍然可见,而不是最后一个。这是类代码。如果有任何同事可以帮助我,我将不胜感激,谢谢。

public class AutoScrollListView : ListView
    {
        private INotifyCollectionChanged _previousObservableCollection;

        public AutoScrollListView(ListViewCachingStrategy cachingStrategy)
            : base(cachingStrategy)
        {
        }

        public AutoScrollListView()
            : base()
        {
        }

        protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);

            if (propertyName == nameof(ItemsSource))
            {
                if (_previousObservableCollection != null)
                {
                    _previousObservableCollection.CollectionChanged -= OnItemsSourceCollectionChanged;
                    _previousObservableCollection = null;
                }

                if (ItemsSource is INotifyCollectionChanged newObservableCollection)
                {
                    _previousObservableCollection = newObservableCollection;
                    newObservableCollection.CollectionChanged += OnItemsSourceCollectionChanged;
                }
            }
        }

        private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace)
            {
                foreach (var item in e.NewItems)
                {
                    // Scroll to the item that has just been added/updated to make it visible
                    ScrollTo(item, ScrollToPosition.End,true);
                    
                }
            }
        }
    }
C# Xamarin Xamarin.Android

评论

0赞 Jianwei Sun - MSFT 11/14/2023
如果它对面临相同问题的其他人有帮助,请接受它作为答案。提前致谢!

答:

1赞 Jianwei Sun - MSFT 11/2/2023 #1

在这里,它不是滚动到最后一个 PL-SQL,而是停留在第一个 PL-SQL 上,它向我展示了滚动的动画,但我添加的第一个 PL-SQL 仍然可见,而不是最后一个。

因为这个:enter image description here

将对项目进行线性搜索,因此,如果同一引用在列表中多次出现,则将滚动到第一个项目。这包括是否启用了分组。

CollectionView 可以满足您的需求:

自动滚动集合视图.cs

public class AutoScrollCollectionView : CollectionView
{
    private INotifyCollectionChanged _previousObservableCollection;

    protected override void OnPropertyChanged ([CallerMemberName] string propertyName = null)
    {
        base.OnPropertyChanged (propertyName);

        if (propertyName == nameof (ItemsSource))
            {
                if (_previousObservableCollection != null)
                    {
                        _previousObservableCollection.CollectionChanged
                            -= OnItemsSourceCollectionChanged;
                        _previousObservableCollection = null;
                    }

                if (ItemsSource is INotifyCollectionChanged
                        newObservableCollection)
                    {
                        _previousObservableCollection = newObservableCollection;
                        newObservableCollection.CollectionChanged
                            += OnItemsSourceCollectionChanged;
                    }
            }
    }

    private void OnItemsSourceCollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Replace)
            {
                ScrollTo (e.NewStartingIndex);
            }
    }
}

XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:control="clr-namespace:Forms1.CustomControls"
             x:Class="Forms1.Page1">
    <ContentPage.Content>
        <StackLayout>
            <control:AutoScrollCollectionView x:Name="collectionview">
                <control:AutoScrollCollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout HeightRequest="100"
                                     Padding="70,30">
                            <Label Text="{Binding .}"/>
                        </StackLayout>
                    </DataTemplate>
                </control:AutoScrollCollectionView.ItemTemplate>
            </control:AutoScrollCollectionView>
            
            <Button Text="click" Clicked="Button_Clicked"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

xaml.cs:

public partial class Page1 : ContentPage
{
    ObservableCollection<string> myList;
    public Page1 ()
    {
        InitializeComponent ();
        myList = new ObservableCollection<string> ();
        myList.Add ("C#");
        myList.Add ("Html");
        myList.Add ("T-SQL");
        myList.Add ("Python");
        myList.Add ("PL-SQL");

        collectionview.ItemsSource = myList;
        BindingContext = this;
    }

    private void Button_Clicked (object sender, EventArgs e)
    {
        myList.Add ("PL-SQL");
    }
}

评论

0赞 Yoandry Castellanos 11/4/2023
谢谢我的朋友,你的回答我解决了这个问题,再次感谢