我正在为图书创建搜索页面。数据库中缺少数据。如果数据大小超过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>
答案 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>