0

I have a ListView control with support for incremental loading of large item collections. The loading of additional items is triggered when the user scrolls down to the bottom ListView's vertical scrollbar. I strive to use MVVM pattern in the implementation (no code-behind), but IMHO in this particular case it's not essential.

I am tinking about introducing a new event (e.g. NeedsMoreItems) and perhaps subclass ListView (ListViewWithIncrementalLoading) so the application won't need to do ScrollChanged events mapping. I haven't implemented custom events for XAML controls before, so I am not quite sure what's the easiest way to achive this. Do I need to create custom control? User control? Use attached events?

If you have code snippets from similar tasks, I will really appreciate it.

4

1 回答 1

1

这不是完整的代码,因为这一切都很难开发,而且代码非常多(在软件 CCFinder 中使用),它也不完美,但它确实可以完成工作。

    <CCFinder:AnimatedScrollViewer VerticalScrollBarVisibility="{Binding IsItemsFound, Converter={StaticResource __boolToVisibilityConverter}}" Margin="36,211,38,72" 
                  ScrollChanged="ScrollViewer_ScrollChanged" HorizontalContentAlignment="Center" Focusable="False" x:Name="ScrolView1">

            <ItemsControl Name="_itemsControl"  ItemsSource="{Binding CurrentImages}"
            ...

在代码隐藏中:

    private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        if (e.VerticalOffset + e.ViewportHeight == e.ExtentHeight)
        {
            var scroller = ((ScrollViewer)sender);
            scroller.ReleaseMouseCapture();
            scroller.InvalidateScrollInfo();
            ((OverviewViewModel)this.DataContext).ShowMoreTriggered();
        }
    }

因此,重要的部分来了:在 ViewModel 类中,我将 MaximumImages 属性设置为更高的值……它从大约 50 开始,然后提高到 251,然后在再次触发时提高到 500。在 MaximumImages 的设置器中,通知 WPF 框架 CurrentImages 已更改,在 CurrentImages 获取器中我有很多笨拙的代码,它们意识到现在的 MaximumImages 数字比以前更高,并向 CurrentImages 添加新项目(全部在吸气剂)。不太好,但它可以工作并且主要在 ViewModel 类中:

    public void ShowMoreTriggered()
    {
        if (Photos != null && !ShowMoreTriggeredActive && MaximumImages < Photos.Count)
        {
            ShowMoreTriggeredActive = true;
            ThreadPool.QueueUserWorkItem(delegate
                                             {
                                                 Thread.Sleep(1000);
                                                 MaximumImages = MaximumImages < 251 ? 251 : 500;
                                                 Thread.Sleep(1500);
                                                 ShowMoreTriggeredActive = false;
                                             });
        }
    }

    private int _maximumImages;
    public int MaximumImages
    {
        get
        {
            return _maximumImages;
        }
        set
        {
            _maximumImages = value;
            InvokePropertyChanged("MaximumImages");
            InvokePropertyChanged("CurrentImages");
        }
    }

当然,如果滚动事件达到最低点,引发用户定义的事件会更优雅,但我想它只会产生更多代码,而不是更少,因为无论如何它肯定会从 ScrollChanged 事件传播.

于 2013-04-10T18:49:26.250 回答