WPF - 在Listbox中绑定大量数据

时间:2010-10-12 10:49:26

标签: wpf data-binding listbox

我正在为图书创建搜索页面。数据库中缺少数据。如果数据大小超过2000,则应用程序将被挂起。列表框的ItemsSource有数据但有些不对的事情正在发生。

代码

 <ListBox Grid.Column="1" 
          x:Name="lbResult"  
          ItemsSource="{Binding}"   
          SelectionChanged="lbResult_SelectionChanged">
    <ListBox.ItemTemplate>
         <DataTemplate>
            <StackPanel Width="320">
                <TextBlock Margin="10">
                   <InlineUIContainer>
                       <TextBlock Foreground="DarkKhaki" Text="{Binding Title}"/>
               </InlineUIContainer>
                   <Run Text=" "/><LineBreak/>
                   <InlineUIContainer>
                       <TextBlock Text=" By "/>
               </InlineUIContainer>
                   <Run Text=" "/>
                   <InlineUIContainer>
                       <TextBlock Text="{Binding Author}"/> 
               </InlineUIContainer>
                </TextBlock>
            </StackPanel>
         </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel IsItemsHost="True" Orientation="Vertical"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

3 个答案:

答案 0 :(得分:7)

应用程序显然是“挂起”,因为数据加载发生在UI线程上。

您应该考虑使用另一种模型,使您能够在另一个线程中加载数据并定期更新UI或在新数据到达时更新UI。

您可以使用ObservableCollection进行此操作。

后台加载线程更新集合,这会向UI线程发出一个事件,指示需要更新。

有一个如何在GALA Soft

上执行此操作的示例

您为集合创建属性(在本例中为只读):

private ObservableCollection<MyDataItem> dataItems;
public ObservableCollection<MyDataItem> DataItems
{
      get { return dataItems; }
}

然后在你的XAML中:

<ListBox ItemsSource="{Binding ElementName=mainWindow, Path=DataItems}"
         ...>
</ListBox>

答案 1 :(得分:2)

您可能遇到的一个问题是您在ItemsPanelTemplate中使用非虚拟化类型的面板(WrapPanel)。这意味着即使只有一小部分数据可见,也会加载所有2000个数据项。默认情况下,ListBox使用VirtualizingStackPanel作为其面板,顾名思义,它提供虚拟化,因此它只会加载可见的数据集元素。

因此,在性能方面的一个简单的解决方法是省去WrapPanel和我们的虚拟化面板,但这显然会改变外观。

如果你特别想要一个WrapPanel,那么WPF没有提供虚拟化的等价物,但是有一些实现,例如http://virtualwrappanel.codeplex.com/

答案 2 :(得分:2)

尝试使用ListView,我遇到了同样的问题。现在我可以瞬间装载超过7000件物品。

像这样:

  <StackPanel Grid.Row="1" Grid.Column="0">
      <ListView 
           Height="100"
           Name="lstPlayerList">
           <ListView.View>
                <GridView>
                     <GridViewColumn 
                         Width="100"           
                         Header="LastName"
                         DisplayMemberBinding="{Binding LastName}">
                     </GridViewColumn>
                 </GridView>
           </ListView.View>
       </ListView>
   </StackPanel>