0

大きなアイテム コレクションのインクリメンタル ロードをサポートする ListView コントロールがあります。ユーザーが一番下の ListView の垂直スクロールバーまでスクロールすると、追加の項目の読み込みがトリガーされます。私は実装でMVVMパターンを使用するよう努めています(コードビハインドなし)が、この特定のケースではIMHOは必須ではありません。

新しいイベント (NeedsMoreItems など) とおそらくサブクラスの ListView (ListViewWithIncrementalLoading) を導入して、アプリケーションが ScrollChanged イベントのマッピングを行う必要がないようにしています。これまで XAML コントロールのカスタム イベントを実装したことがないため、これを実現する最も簡単な方法が何であるかはよくわかりません。カスタム コントロールを作成する必要がありますか? ユーザーコントロール?添付イベントを使用しますか?

同様のタスクのコード スニペットがあれば、本当に感謝します。

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 のセッターでは、CurrentImages が変更されたことが WPF フレームワークに通知されます。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 に答える