質問

を持っています ItemsControl ただし、仮想化したいデータのリストが含まれています。 VirtualizingStackPanel.IsVirtualizing="True" で動作しないようです ItemsControl.

これは本当にそうですか、それとも私が知らないこれを行う別の方法がありますか?

テストするには、次のコードブロックを使用しています。

<ItemsControl ItemsSource="{Binding Path=AccountViews.Tables[0]}"
              VirtualizingStackPanel.IsVirtualizing="True">
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBlock Initialized="TextBlock_Initialized"  
                   Margin="5,50,5,50" Text="{Binding Path=Name}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

変更した場合 ItemsControlListBox, 、私はそれを見ることができます Initialized イベントはほんの一握りの回数しか実行されません(巨大なマージンはちょうどあるので、私はいくつかのレコードを実行する必要があります)。 ItemsControl すべてのアイテムが初期化されます。

設定しようとしました ItemsControlPanelTemplateVirtualizingStackPanel しかし、それは助けにはならないようです。

役に立ちましたか?

解決

実際には、単に作る以上のものがあります ItemsPanelTemplate 使用する VirtualizingStackPanel. 。デフォルト ControlTemplate にとって ItemsControl 持っていない ScrollViewer, 、これが仮想化の鍵です。デフォルトのコントロールテンプレートに追加 ItemsControl (のコントロールテンプレートを使用します ListBox テンプレートとして)は以下を提供します。

<ItemsControl
    VirtualizingStackPanel.IsVirtualizing="True"
    ScrollViewer.CanContentScroll="True"
    ItemsSource="{Binding Path=AccountViews.Tables[0]}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock
                Initialized="TextBlock_Initialized"
                Text="{Binding Path=Name}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
        <Border
            BorderThickness="{TemplateBinding Border.BorderThickness}"
            Padding="{TemplateBinding Control.Padding}"
            BorderBrush="{TemplateBinding Border.BorderBrush}"
            Background="{TemplateBinding Panel.Background}"
            SnapsToDevicePixels="True">
                <ScrollViewer
                    Padding="{TemplateBinding Control.Padding}"
                    Focusable="False">
                    <ItemsPresenter
                        SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </ScrollViewer>
            </Border>
            </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

(ところで、デフォルトのコントロールテンプレートを調べるための優れたツールは テンプレートを見せてください)

注意すべきこと:

設定する必要があります ScrollViewer.CanContentScroll="True", 、 見る ここ なぜ。

また、私が置くことに注意してください VirtualizingStackPanel.VirtualizationMode="Recycling". 。これにより、回数が減ります TextBlock_Initialized ただし、画面上に多くのテキストブロックが表示されています。 UI Virtualizationの詳細をお読みください ここ.

編集:明白を述べるのを忘れました:代替ソリューションとして、あなたはただ交換することができます ItemsControlListBox :)また、これをチェックしてください MSDNページでパフォーマンスを最適化します そしてそれに注意してください ItemsControl 「パフォーマンス機能を実装するコントロール」テーブルには含まれていないため、コントロールテンプレートを編集する必要があります。

他のヒント

Davidnの答えに基づいて、ここにあなたがそれを仮想化するためにitemsControlで使用できるスタイルがあります:

<!--Virtualised ItemsControl-->
<Style x:Key="ItemsControlVirtualizedStyle" TargetType="ItemsControl">
    <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/>
    <Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ItemsControl">
                <Border
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    Padding="{TemplateBinding Control.Padding}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Background="{TemplateBinding Panel.Background}"
                    SnapsToDevicePixels="True"
                >
                    <ScrollViewer Padding="{TemplateBinding Control.Padding}" Focusable="False">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

必ずしもそれを望んでいない行の選択を許可するため、リストボックスを使用するという提案が好きではありません。

デフォルトだけです ItemsPanel ではありません VirtualizingStackPanel. 。あなたはそれを変更する必要があります:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top