使用 UWP 模拟无限滚动选择器的最简单方法 [英] Easiest way to simulate infinite scrolling selector with UWP

查看:25
本文介绍了使用 UWP 模拟无限滚动选择器的最简单方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设计一个控件,允许用户向上或向下滚动一系列数字(例如 0-2000),并具有类似向上或向下滚动列表的感觉.

I am trying to design a control that would allow users to scroll up or down a range of numbers (e.g. 0-2000) with a similar feel of scrolling up or down a list.

我尝试在 Flyout 中使用 ListViewGridView 来实现这一点,但是仅仅加载几千个项目实在是太慢了.

I tried to use a ListView or GridView inside a Flyout for this, but it's simply too slow just to load a couple thousand items.

现在我认为最好的方法可能是简单地模拟列表滚动而实际上没有任何项目(即无限滚动选择器).关于使用什么控件作为实现这种无限选择器的基础有什么建议吗?

Now I'm thinking the best way might be to simply simulate the list scrolling without actually having any items (i.e. an infinite scrolling selector). Any suggestions on what control to use as a base to implement such an infinite selector?

推荐答案

这里是循环虚拟化滚动条.它只保留 5 个项目,因此您可以添加很多项目.对于选择,您可以在 Item 上添加一个事件.

Here is looped virtualized scroller. It keeps only 5 items so you could add a lot of them. For selection, you may add an event on Item.

public sealed partial class MainPage
{
    private static int Count = 20;
    private static float ItemSize = 128;

    private Visual _spawnerVisual;
    private readonly List<ItemModel> _items = new List<ItemModel>();
    private readonly List<Item> _selectedItems = new List<Item>();
    private int _index;

    private static readonly Random Random = new Random();

    public MainPage()
    {
        InitializeComponent();
        Loaded += MainPage_Loaded;
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        PopulateItems();
        SetInitialItems();
    }

    private void PopulateItems()
    {
        for (int i = 0; i < Count; i++)
        {
            _items.Add(new ItemModel());
        }
    }

    private void SetInitialItems()
    {
        _index = -5;
        for (int i = 0; i < 5; i++)
        {
            KillAtTop(true);
        }
        _spawnerVisual = ElementCompositionPreview.GetElementVisual(Spawner);
    }

    private void KillAtTop(bool atTop)
    {
        if (atTop)
        {
            if (_selectedItems.Count > 4)
            {
                _selectedItems.RemoveAt(0);
                Spawner.Children.RemoveAt(0);
            }

            var index = GetIndex(_index + 3);

            var item = new Item
            {
                Id = index,
                BackColor = Color.FromArgb(255, (byte)Random.Next(0, 255), (byte)Random.Next(0, 255), (byte)Random.Next(0, 255)),
                ItemSize = ItemSize,
                ItemModel = _items[index],
                OffsetY = (_index + 6) * ItemSize
            };
            _selectedItems.Add(item);
            Spawner.Children.Add(item);
            _index++;
        }
        else
        {
            if (_selectedItems.Count > 4)
            {
                _selectedItems.RemoveAt(_selectedItems.Count - 1);
                Spawner.Children.RemoveAt(Spawner.Children.Count - 1);
            }

            var index = GetIndex(_index - 3);

            var item = new Item
            {
                Id = index,
                BackColor = Color.FromArgb(255, (byte)Random.Next(0, 255), (byte)Random.Next(0, 255), (byte)Random.Next(0, 255)),
                ItemSize = ItemSize,
                ItemModel = _items[index],
                OffsetY = _index * ItemSize
            };
            _selectedItems.Insert(0, item);
            Spawner.Children.Insert(0, item);
            _index--;
        }
    }

    private int GetIndex(int index)
    {
        index = index % _items.Count;
        if (index > _items.Count - 1) return index - _items.Count;
        if (index < 0) return _items.Count + index;
        return index;
    }

    private void Slider_OnSetDelta(float deltaY)
    {
        SetPosition(deltaY);
    }

    public void SetPosition(float offsetY)
    {
        _spawnerVisual.Offset += new Vector3(0, offsetY / 10, 0);

        if (_spawnerVisual.Offset.Y > -ItemSize * _index + ItemSize)
        {
            KillAtTop(false);
        }

        if (_spawnerVisual.Offset.Y < -ItemSize * _index)
        {
            KillAtTop(true);
        }

    }
}

只需添加您的 ItemControl 并调用 SetPosition 即可滚动.应该是这样的:

Just add your ItemControl and call SetPosition to scroll. Should look like this:

这篇关于使用 UWP 模拟无限滚动选择器的最简单方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆