2010-05-06 12 views
103

Sanallaştırmak istediğiniz bir veri listesini içeren bir ItemsControl sahibim, ancak VirtualizingStackPanel.IsVirtualizing="True" bir ItemsControl ile çalışmıyor gibi görünüyor.Bir ItemsControl sanallaştırılıyor mu?

Bu gerçekten böyle mi, yoksa bunu yapmanın başka bir yolu var mı? Bir ListBox için ItemsControl değiştirirseniz ben Initialized olay sadece birkaç kez görünse (büyük marjlar ishal olduğunu görebilirsiniz,

<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> 

:

ben aşağıdaki kod bloğunu kullanıyoruz test etmek sadece birkaç kayıttan geçmek zorundayım, ancak ItemsControl olarak her öğe başlıyor.

ItemsControlPanelTemplate'u VirtualizingStackPanel'a ayarlamayı denedim, ancak bu yardımcı olmadı.

cevap

178

. ItemsControl için varsayılan ControlTemplate, sanallaştırmanın anahtarı olan bir ScrollViewer ürününe sahip değildir. (Şablon olarak ListBox kontrol şablon kullanarak) ItemsControl için varsayılan kontrol şablonuna ekleme aşağıdaki bize verir:

<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> 

(BTW, varsayılan kontrol şablonları bakmak için harika bir araç Show Me The Template olan)

Yapılacaklar:

ScrollViewer.CanContentScroll="True" ayarını yapmalısınız, neden için here'a bakınız. Ayrıca, VirtualizingStackPanel.VirtualizationMode="Recycling"'u eklediğime de dikkat edin. Bu sayede, TextBlock_Initialized numaralarının sayısını azaltacaktır ancak ekranda çok sayıda TextBlock görülecektir. UI sanallaştırma here hakkında daha fazla bilgi edinebilirsiniz.

DÜZENLEME: Bildiklerimi unuttum: alternatif çözüm olarak, sadece, aynı zamanda ListBox :) ile ItemsControl yerine bu Optimizing Performance on MSDN page kontrol etmek ve ItemsControl "Performans Özellikleri ygulama Denetimler" olmadığını fark edebilirsiniz tablo Bu yüzden kontrol şablonunu düzenlememiz gerekiyor.

+1

Teşekkür ederim, tam olarak aradığım şey bu!Bir liste kutusundan farklı bir seçim davranışı arıyordum ve o sırada bir ürün kontrolüyle yapmanın en kolay olacağını düşündüm. – Rachel

+0

ListView bunun için de çalışır. –

+0

Eğer bu itemscontrol daha iç içe ise, ayrıca bir yükseklik de vermelisiniz. Aksi takdirde, scrollviewer gösterilmez. – buckley

-3

Varsayılan olarak ItemsPanel, VirtualizingStackPanel değil. Bunu değiştirmek gerekir: aslında çok daha kendisine sadece ItemsPanelTemplate kullanımını VirtualizingStackPanel yapmak yerine var

<ItemsControl> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 
+0

Teşekkürler, ama bunu zaten denedim ve işe yaramadı. – Rachel

+6

Çözüm eksik olduğu için onu reddediyorum. Sanallaştırmayı etkinleştirmek için şablonda bir scrollviewer kullanmanız gerekir. –

22

Yapı DavidN cevabı burada, bunu sanallaştırma için ItemsControl kullanabileceğiniz bir stil: Ben senin ne satırların seçimine izin olarak, bir liste kutusu kullanmak öneriyi beğenmedi

<!--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> 

mutlaka istemiyorum.