133

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すべてのアイテムが初期化されます。

をに設定してみItemsControlPanelTemplateましたVirtualizingStackPanelが、役に立たないようです。

4

3 に答える 3

236

実際には、単にItemsPanelTemplate使用するだけではありませんVirtualizingStackPanel。のデフォルトControlTemplateには、仮想化の鍵となる、がありItemsControlません。ScrollViewerのデフォルトのコントロールテンプレートに追加するとItemsControl(のコントロールテンプレートをテンプレートListBoxとして使用)、次のようになります。

<ItemsControl ItemsSource="{Binding AccountViews.Tables[0]}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Initialized="TextBlock_Initialized"
                 Text="{Binding Name}" />
    </DataTemplate>
  </ItemsControl.ItemTemplate>

  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <VirtualizingStackPanel IsVirtualizing="True"
                              VirtualizationMode="Recycling" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.Template>
    <ControlTemplate TargetType="ItemsControl">
      <Border BorderThickness="{TemplateBinding BorderThickness}"
              BorderBrush="{TemplateBinding BorderBrush}"
              Background="{TemplateBinding Background}">
        <ScrollViewer CanContentScroll="True" 
                      Padding="{TemplateBinding Padding}"
                      Focusable="False">
          <ItemsPresenter />
        </ScrollViewer>
      </Border>
    </ControlTemplate>
  </ItemsControl.Template>
</ItemsControl>

(ところで、デフォルトのコントロールテンプレートを確認するための優れたツールはShow Me The Templateです)

注意事項:

設定する必要があります。理由については、こちらScrollViewer.CanContentScroll="True"をご覧ください。

また、私が置いたことに注意してVirtualizingStackPanel.VirtualizationMode="Recycling"ください。これにより、呼び出される回数が減りTextBlock_Initializedますが、画面には多くのTextBlockが表示されます。UI仮想化の詳細については、こちら をご覧ください。

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

于 2010-05-06T20:25:14.470 に答える
44

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>

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

于 2012-11-15T06:00:57.613 に答える
-4

デフォルトItemsPanelが ではないというだけですVirtualizingStackPanel。変更する必要があります:

<ItemsControl>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>
于 2010-05-06T20:15:16.470 に答える