65

たくさんのアイテムが入った非常に大きなツリーを表示しています。これらの各項目は、関連する UserControl コントロールを通じてユーザーに情報を表示します。この情報は 250 ミリ秒ごとに更新する必要があります。これは、リフレクションを使用してそれらの値の一部にアクセスしているため、非常にコストのかかる作業になる可能性があります。私の最初のアプローチは IsVisible プロパティを使用することでしたが、期待どおりに機能しません。

コントロールがユーザーに「見える」かどうかを判断する方法はありますか?

注: IsExpanded プロパティを使用して折りたたまれたノードの更新をスキップしていますが、一部のノードには 100 以上の要素があり、グリッド ビューポートの外側にある要素をスキップする方法が見つかりません。

4

4 に答える 4

89

先ほど書いたこの小さなヘルパー関数を使用して、特定のコンテナーで要素がユーザーに表示されるかどうかを確認できます。true要素が部分的に表示されている場合、関数は戻ります。完全に表示されているかどうかを確認する場合は、最後の行を に置き換えrect.Contains(bounds)ます。

private bool IsUserVisible(FrameworkElement element, FrameworkElement container)
{
    if (!element.IsVisible)
        return false;

    Rect bounds = element.TransformToAncestor(container).TransformBounds(new Rect(0.0, 0.0, element.ActualWidth, element.ActualHeight));
    Rect rect = new Rect(0.0, 0.0, container.ActualWidth, container.ActualHeight);
    return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}

あなたの場合、elementユーザーコントロールとcontainerウィンドウになります。

于 2009-10-05T00:40:18.803 に答える
5

含まれているコントロールに次のプロパティを使用します。

VirtualizingStackPanel.IsVirtualizing="True" 
VirtualizingStackPanel.VirtualizationMode="Recycling"

次に、データ項目の INotifyPropertyChanged.PropertyChanged サブスクライバーを次のようにリッスンします。

    public event PropertyChangedEventHandler PropertyChanged
    {
        add
        {
            Console.WriteLine(
               "WPF is listening my property changes so I must be visible");
        }
        remove
        {
            Console.WriteLine("WPF unsubscribed so I must be out of sight");
        }
    }

詳細については、http: //joew.spaces.live.com/?_c11_BlogPart_BlogPart=blogview&_c=BlogPart&partqs=cat%3DWPFを参照してください。

于 2009-12-04T10:20:15.210 に答える