从WPF控件引发用户定义的事件

时间:2013-04-10 15:54:57

标签: wpf xaml events custom-controls

我有一个ListView控件,支持大型项目集合的增量加载。当用户向下滚动到底部ListView的垂直滚动条时,会触发加载其他项目。我努力在实现中使用MVVM模式(没有代码隐藏),但在这种特殊情况下恕我直言并不是必需的。

我正在讨论引入一个新事件(例如NeedsMoreItems)和子类ListView(ListViewWithIncrementalLoading),因此应用程序不需要进行ScrollChanged事件映射。我之前没有为XAML控件实现自定义事件,所以我不太确定实现这个的最简单方法是什么。我需要创建自定义控件吗?用户控制?使用附加活动?

如果你有来自类似任务的代码片段,我将非常感激。

1 个答案:

答案 0 :(得分: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的setter中,WPF框架被通知CurrentImages已经改变,并且在CurrentImages getter中我有很多笨重的代码,它们意识到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事件。