问题
I am observing that the Listview in my app fails to display the text of listview items when the item count exceeds 400 items.
My guess is that this is a memory issue with the phone and not a pattern with larger devices.
I assume that I will need to only add a fraction of the items that my listview's itemsource is based on.
What is the best approach for managing a listview that's responsible for displaying large amounts of data?
Here's my XAML:
<ListView x:Name="ContactList" ScrollViewer.VerticalScrollBarVisibility="Visible"
attachedProperties:CategoryHelper.Category="{Binding SelectedCategory, Mode=TwoWay}"
ItemsSource="{Binding SelectedCategory.Contacts}"
VirtualizingStackPanel.VirtualizationMode="Recycling"
SelectedItem="{Binding SelectedContact, Mode=TwoWay}"
HorizontalContentAlignment="Left"
Margin="58,175,0,0"
Height="425"
Width="425"
Background="Transparent" Foreground="#FF333747" VerticalAlignment="Top" Canvas.ZIndex="99" HorizontalAlignment="Left" >
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter VirtualizingStackPanel.VirtualizationMode="{TemplateBinding VirtualizingStackPanel.VirtualizationMode}" />
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="FontSize" Value="26" />
<Setter Property="Margin" Value="0,10" />
<Setter Property="Foreground" Value="#FF333747" />
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Style="{StaticResource CheckBoxStyle1}"
Loaded="CheckBox_Loaded"
Visibility="{Binding ElementName=grid, Path=DataContext.BroadcastActivated, Converter={StaticResource BoolToVisibilityConverter}, Mode=TwoWay}"
Margin="0,-8" BorderBrush="#FF4E58BC" Checked="ContactChecked" Unchecked="ContactUnchecked">
</CheckBox>
<TextBlock Text="{Binding DisplayName}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Holding">
<behaviors:MoveContactAction />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Family" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Friend" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Business" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
<MenuFlyoutItem Text="Others" Command="{Binding ElementName=grid, Path=DataContext.MoveCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=Text}" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Update: I can now get a large amount of items to display in a Listview.
However, I am unable to apply a DataTemplate without observing the same issue of items not being displayed.
This works:
<ListView x:Name="ContactList" ItemsSource="{Binding SelectedCategory.Contacts}"
Height="425"
Width="425"
Margin="58,175,0,0" Canvas.ZIndex="99"
Background="Transparent" Foreground="#FF333747"
VerticalAlignment="Top" HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="Hello Wworld" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
This doesn't:
<ListView x:Name="ContactList" ItemsSource="{Binding SelectedCategory.Contacts}"
Height="425"
Width="425"
Margin="58,175,0,0" Canvas.ZIndex="99"
Background="Transparent" Foreground="#FF333747"
VerticalAlignment="Top" HorizontalAlignment="Left">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding DisplayName}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListView>
It appears that displaying listview items using a data template fails once a binding is applied. How can I resolve this?
回答1:
yes, you can't put them all in memory. you can use Virtualizing. here is link:http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.isvirtualizing.aspx
回答2:
Keeping in mind that this is a phone, why would you like more than 400 items on a list to begin with? Think how the user will work with that data to begin with.
If you have more than 400 items, mabye you should have some selectinos to narrow them down. Maybe you can have result "pages", and bunch them in a number that is easily digested, both for the phone, but more importantly, the user.
Having said that, and in addition to Rang's answer, you might be able to try and allocated more memory to your application. Have a look in this post, but specifically:
<FunctionalCapabilities>
<FunctionalCapability Name="ID_FUNCCAP_EXTEND_MEM"/>
</FunctionalCapabilities>
回答3:
My list was displaying several items that had empty strings.
As a result of this list being sorted in ascending order, the items that displayed empty text showed up at the beginning of the list while the other items did exist but were not within the scrollviewer's viewport.
As a result I did this:
if (string.IsNullOrWhiteSpace(contact.DisplayName))
{
continue;
}
来源:https://stackoverflow.com/questions/25478245/listview-fails-to-display-text-of-list-items-when-item-count-exceeds-400-items