2011-04-04 105 views
2

我將一個相當龐大的項目集合綁定到一個ItemsControl。 ItemsControl的ItemTemplate被設置爲一個自定義的用戶控件來渲染數據。 ItemControl是虛擬化的。WPF虛擬化大項目

現在的問題是ItemsControl中的每個用戶控件都會變得相當高。它甚至有可能比實際的屏幕高度變得更高。如果發生這種情況,我無法看到其餘的用戶控件,因爲只要我滾動集合中的下一個項目被帶到屏幕的頂部,只有一半顯示的項目完全滾動到視圖外。如果我不使用虛擬化,那麼一切顯然工作正常。

有什麼辦法可以避開這種行爲,仍然可以使用虛擬化?

+0

您能否提供一些示例xaml來顯示您目前正在做什麼來實現此目的?我會發現看你如何去實現你的ItemsControl很有幫助。 – Scott 2011-04-04 15:21:11

回答

1

有一種解決方法,但它並不完全漂亮......基本上,它是實現您自己的虛擬化面板。正如您正確地注意到的那樣,內置面板的行爲是從最頂端的項目的頂部進行繪製 - 在屏幕頂部不能有一半項目。這基本上是因爲它使得虛擬化代碼輕得多,並且在大多數情況下這不是問題。

您可以創建自己的面板(衍生自VirtualizingPanel),該面板沒有此限制。這不是直截了當的,但它是值得的結果!

在你的情況,該項目如果所有是固定的大小和超出屏幕的大小,你會發現它並不是很複雜 - 很多複雜的正值當項目是不同的尺寸。

+0

我已經實現了虛擬化面板,並且提供了您提到的可變大小的項目問題......您是否有任何指示? – Sheridan 2012-10-17 20:29:18

1

您的ItemsControl的ScrollViewer是否有內容滾動設置?編輯2:正如Dan所說,只要您嘗試平滑滾動,就會失去虛擬化。我不知道你的要求是什麼,但一個潛在的解決方法可能是類似以下內容:

<Window x:Class="TestApp11.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
    xmlns:l="clr-namespace:TestApp11" 
    Title="Window1" Height="200" Width="200"> 
    <Grid> 
     <ItemsControl> 
      <ItemsControl.Template> 
       <ControlTemplate> 
        <ScrollViewer CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling"> 
         <ItemsPresenter /> 
        </ScrollViewer> 
       </ControlTemplate> 
      </ItemsControl.Template> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate DataType="{x:Type ListBoxItem}"> 
        <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto" MaxHeight="160"> 
         <Border Height="200" Width="140" BorderBrush="Red" BorderThickness="10" Margin="1" Background="Blue" /> 
        </ScrollViewer> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel VirtualizingStackPanel.VirtualizationMode="Recycling" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
      <ContentElement /> 
     </ItemsControl> 
    </Grid> 
</Window> 

從本質上講,你可以有ItemTemplate中緊裹的ScrollViewer內的用戶控件項目。我沒有在我的示例中顯示它,但是您可以將ScrollViewer的MaxHeight(ItemTemplate內)綁定到可視區域的高度,然後垂直滾動條僅在您的UserControl太大而不能顯示適合在屏幕上。

我可以看到這可能是太難看的解決方案給客戶,但在這種情況下,我認爲唯一的選擇是去丹建議的路線。

+0

我認爲這個問題足以說明問題! – 2011-04-04 14:45:15

+0

@丹Puzey,這個問題很好解釋,是的。但是,往往沒有什麼細節可以被排除在原因之外。我個人發現能夠重現別人正在發生的問題是有益的,然後提供幫助。我並不打算對這篇文章發表評論,因爲它沒有提供代碼。我只是想幫助解決這個問題,並且發現看到一些代碼很有用。 (它可以幫助我瞭解其他人如何做事) – Scott 2011-04-04 14:51:38

+0

哦...並且感謝您的投票,我認爲試圖提供幫助是被某些人看不起的。 – Scott 2011-04-04 14:54:25