2012-10-01 42 views
0

使用衍生自ListBox的自定義控件的模板會導致ItemSource的過濾變慢。過濾是在控件綁定的ItemSource的get中完成的。當使用正常的ListBox時,此問題不存在,那麼爲什麼它應該與定製的ListBox有什麼不同?使用自定義ListBox ControlTemplate進行性能降級

過濾:

public IEnumerable<LibraryViewModel> Libraries { 
    get { 
     if (!string.IsNullOrEmpty(this.LibrarySearchString)) 
      return _libraries.Where(lib => IsLibraryMatch(lib, this.LibrarySearchString)); 
     else 
      return _libraries.OrderBy(lib => !lib.IsFavourite); 
    } 
} 

使用控制:

<con:FilterListBox Grid.Row="1" 
        ItemsSource="{Binding Libraries}" 
        SelectedItem="{Binding SelectedLibrary}" 
        ItemTemplate="{StaticResource 
            LibraryItemTemplate}"       
        SearchString="{Binding LibrarySearchString, Mode=TwoWay}" 
        IsSearching="False" 
        Margin="4"/> 

控制模板:

<Style x:Key="{x:Type con:FilterListBox}" TargetType="{x:Type con:FilterListBox}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type con:FilterListBox}"> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="Auto"/> 
         <RowDefinition/> 
        </Grid.RowDefinitions> 

        <DockPanel Grid.Row="0"> 
         <TextBlock Text="Search" 
            VerticalAlignment="Center"/> 
         <TextBox Text="{Binding RelativeSource={RelativeSource TemplatedParent}, 
               Path=SearchString, 
               UpdateSourceTrigger=PropertyChanged}" 
           Margin="4,0,0,0"/> 
        </DockPanel> 

        <ScrollViewer Grid.Row="1" CanContentScroll="True"> 
         <StackPanel IsItemsHost="True" 
            HorizontalAlignment="Stretch"/> 
        </ScrollViewer> 

        <TextBlock Grid.Row="1" 
           Text="Searching..." 
           HorizontalAlignment="Center" 
           VerticalAlignment="Center" 
           Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, 
                Path=IsSearching, 
                Converter={StaticResource CollapsedIfFalseConverter}}"/> 
       </Grid> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

感謝您的幫助。

回答

4

您的FilterListBox的緩慢行爲可能伴隨着虛擬化問題。您用簡單的StackPanel替換了ListBox的ItemsHost。默認情況下,ListBox使用VirtualizingStackPanel,只要有可能就虛擬化Items。請參閱默認的ListBox模板。如果您有一個簡單的StackPanel作爲ItemsPresenter,那麼當您的過濾器發生更改時,ListBox必須重新呈現每個項目。根據項目的數量,這可能會導致您的行爲緩慢。嘗試使用默認的itemshost代替。你也應該知道,虛擬化只能用'簡單'項目(基本上每個項目的高度相同)。

+0

非常感謝你的回答,明天我會放棄它。我在我的列表中有大約1000個項目,如果我做得更少,那麼性能問題就會消失,所以我相信你是對的! – Coder1095

+2

應該指出的是,虛擬化你的ListBox可能比使用'VirtualizingStackPanel'更多。請參閱[本答案](http://stackoverflow.com/a/2784220/302677)以獲取更多詳細信息 – Rachel

+0

+1是的我忘了提及。你必須設置更多的屬性來實現虛擬化。 Rachel鏈接中的答案提供了所需的一切。謝謝。 – JanW