List view resets its scroll position on item sourc

2019-08-10 15:42发布

问题:

I am facing a problem in my windows phone 8.1 app where if I am adding an element in the listview's itemsource, the listview resets its scroll position.

To explain, if i scroll to bottom of the list view and insert an element to the top of the binded OC, the listview jumps to top automatically.

I want it to remain as it is. How to fix this?

CODE

Code Behind

public sealed partial class MainPage : Page
{
    public ObservableCollection<String> Collection = new ObservableCollection<string>();

    private bool incall;
    private int offset;
    int _noofelements;
    ScrollViewer _scrollViewer;

    public MainPage()
    {
        this.InitializeComponent();

        this.NavigationCacheMode = NavigationCacheMode.Required;
        listview.ItemsSource = Collection;
        addNumber(0);
    }

    public static ScrollViewer GetScrollViewer(DependencyObject depObj)
    {
        if (depObj is ScrollViewer) return depObj as ScrollViewer;

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            var child = VisualTreeHelper.GetChild(depObj, i);

            var result = GetScrollViewer(child);
            if (result != null) return result;
        }
        return null;
    }

    private void OnViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
    {
        ScrollViewer view = (ScrollViewer)sender;
        if ((view.VerticalOffset > 0.9 * view.ScrollableHeight) & !incall)
        {
            incall = true;
            addNumber(++offset);
        }
    }

    private void addNumber(int offset)
    {
        int start = offset * 20;
        for (int i = start; i < start + 20; i++)
        {
            if (i % 20 == 0)
                Collection.Insert(0, (_noofelements++).ToString());
            else
                Collection.Add((_noofelements++).ToString());
        }

        incall = false;
    }

    private void listview_Loaded(object sender, RoutedEventArgs e)
    {
        _scrollViewer = GetScrollViewer(listview);
        if (_scrollViewer != null)
        {
            _scrollViewer.ViewChanged += OnViewChanged;
        }
    }
}

UI

<Grid>
    <ListView x:Name="listview" Loaded="listview_Loaded">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsStackPanel ItemsUpdatingScrollMode="KeepItemsInView"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Margin="25" FontSize="32" Text="{Binding}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>