oim*_*tro 5 c# memory wpf listbox listboxitems
好吧,我有一个WPF应用程序,我ListBoxItem
在资源字典中创建自己的,如下所示:
<DataTemplate x:Key="StationItem">
<Grid x:Name="Gridder" Tag="{Binding SItem.StationName}" Width="125" Height="55">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="Rectagler" Width="120" Height="50" RadiusX="5" RadiusY="5" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.ColumnSpan="2" Grid.RowSpan="2" StrokeThickness="1" Stroke="Black">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFF3A00" Offset="0"/>
<GradientStop Color="#FFE88D20" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" x:Name="StationName" Text="{Binding SItem.StationName}" Foreground="Black" FontSize="14" FontWeight="SemiBold" TextWrapping="NoWrap" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0"/>
<TextBlock Grid.Column="0" Grid.Row="1" x:Name="StationCountry" Text="{Binding SItem.StationCountry}" Foreground="WhiteSmoke" FontSize="11" FontWeight="Light" TextWrapping="NoWrap" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,8"/>
<Image Tag="{Binding SItem.StationName}" Width="15" Height="15" RenderOptions.BitmapScalingMode="HighQuality" Grid.Column="1" Grid.Row="1" Source="{Binding FavSource}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,10,10"/>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Rectagler" Property="Width" Value="125"/>
<Setter TargetName="Rectagler" Property="Height" Value="55"/>
<Setter TargetName="StationName" Property="Foreground" Value="White"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
一个ListBox
是这样的:
<ListBox x:Name="StationsListLB" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="5" ItemTemplate="{DynamicResource GenreStyle}" ItemContainerStyle="{DynamicResource ContainerStyle}" Background="{x:Null}" BorderBrush="{x:Null}" PreviewMouseLeftButtonDown="StationsListLB_PreviewMouseLeftButtonDown" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Disabled" PreviewMouseDoubleClick="StationsListLB_PreviewMouseDoubleClick">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical" MaxHeight="220" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
ListBox
当用户选择电台的类型时,我会填充我的项目,方法如下:
public class Stations
{
public StationItem SItem { get; set; }
public string FavSource { get; set; }
}
public class StationItem
{
public string StationName { get; set; }
public string StationUrl { get; set; }
public string StationGenre { get; set; }
public string StationWebsite { get; set; }
public string StationCountry { get; set; }
}
private void LoadStationByGenre(string Genre)
{
StationsListLB.Items.Clear();
StationsListLB.ItemTemplate = (DataTemplate)FindResource("StationItem");
IEnumerable<Stations> results = StationList.Where(s => s.SItem.StationGenre.Equals(Genre));
foreach (var Station in results)
{
StationsListLB.Items.Add(Station);
}
}
Run Code Online (Sandbox Code Playgroud)
注意: 每个StationGenre都会填充ListBox
至少1000个StationItems
.
我的代码工作正常,并以40MB的内存(窗口任务管理器)开始.但每当我选择一种类型并填充我的内存时ListBox
,内存会以100MB的速度爆炸.然后我选择另一种类型的内存进一步爆炸.我认为,与ListBox.Items.Clear();
该ListBoxItems
会从内存中被破坏了,但是这并不发生.
我试图从我的图像中删除ListoBoxItemTemplate
并检查我的应用程序的内存,但没有看到真正的区别(约4-7 MB的差异).
所以我的答案是:在添加项目时,如何让我的应用程序消耗更少的内存ListBox
?
提前致谢!!
尝试使用VirtualizingStackPanel.VirtualizationMode="Recycling"
来提高性能。引用自MSDN:
默认情况下,VirtualizingStackPanel 为每个可见项目创建一个项目容器,并在不再需要时(例如当项目滚动到视图之外时)将其丢弃。当 ItemsControl 包含大量项目时,创建和丢弃项目容器的过程可能会对性能产生负面影响。当 VirtualizingStackPanel.VirtualizationMode 设置为 Recycling 时,VirtualizingStackPanel 会重用项目容器,而不是每次都创建一个新容器。