c# - WPF 列表框项目消耗太多内存

标签 c# wpf memory 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>

像这样的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>

当用户选择电台的流派时,我会填充我的 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);
        }
    }

注意: 每个 StationGenre 都会用至少 1000 个 StationItems 填充我的 ListBox

我的代码工作正常,开始时内存为 40MB(窗口任务管理器)。但是每当我选择一种类型并填充我的 ListBox 时,内存会爆炸 100MB。然后我选择另一种类型,内存会进一步爆炸。我认为使用 ListBox.Items.Clear(); ListBoxItems 也会从内存中销毁,但这并没有发生。

我尝试从我的 ListoBoxItemTemplate 中删除图像并检查了我的应用程序的内存,但没有发现真正的差异(大约 4-7 MB 的差异)。

所以我的答案是:在 ListBox 中添加项目时,如何让我的应用程序占用更少的内存?

提前致谢!

最佳答案

尝试使用 VirtualizingStackPanel.VirtualizationMode="Recycling" 来提高性能。引自 MSDN :

By default, a VirtualizingStackPanel creates an item container for each visible item and discards it when it is no longer needed (such as when the item is scrolled out of view). When an ItemsControl contains a lot of items, the process of creating and discarding item containers can negatively affect performance. When VirtualizingStackPanel.VirtualizationMode is set to Recycling, the VirtualizingStackPanel reuses item containers instead of creating a new one each time.

关于c# - WPF 列表框项目消耗太多内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18171561/

相关文章:

c# - 在 wpf 中重新加载图像

wpf - 为什么我的双向 WPF 绑定(bind)变得分离?

c++ - 使用太多内存(我认为)

.net - 移动设备上的 OutOfMemoryException

delphi - 在Delphi中,将所有者设置为Application而不是nil有什么好处?

c# - 如何在 C# 中启用 XSLT 脚本 ..?

c# - 在 VSTO 插件中捕获 Windows 消息

javascript - 发送 JSON 对象。如何设置简单的 .net Controller 方法来接收此类型?

wpf - 从模型更新 ViewModel 中的属性的正确方法

c# - 两个数组合并成一个字典