C# WPF ListboxItems占用太多内存

C# WPF ListboxItems占用太多内存,c#,wpf,memory,listbox,listboxitems,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 He

好的,我有一个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>
 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);
        }
    }
当用户选择电台的类型时,我使用如下方法填充我的
列表框
项:

    <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>
 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);
        }
    }
公共类电台
{
公共StationItem站点{get;set;}
公共字符串FavSource{get;set;}
}
公共阶级主义
{
公共字符串StationName{get;set;}
公共字符串StationUrl{get;set;}
公共字符串StationGenre{get;set;}
公共字符串站网站{get;set;}
公共字符串StationCountry{get;set;}
}
专用void LoadStationByGene(字符串类型)
{
StationsListLB.Items.Clear();
StationListLB.ItemTemplate=(DataTemplate)FindResource(“StationItem”);
IEnumerable results=StationList.Where(s=>s.SItem.StationGenre.Equals(Genre));
foreach(结果中的var站)
{
StationListLB.Items.Add(站点);
}
}
注意:每个StationEnre将使用至少1000个
StationItems
填充我的
列表框

我的代码运行良好,从40MB内存(窗口任务管理器)开始。但每当我选择一种类型并填充我的
列表框时,内存会以100MB的速度爆炸。然后我选择另一种类型,内存会进一步爆炸。我认为使用
ListBox.Items.Clear()列表框项也将从内存中销毁,但不会发生这种情况

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

所以我的答案是:在
列表框中添加项目时,如何使我的应用程序消耗更少的内存


提前谢谢

尝试使用
virtualizengstackpanel.VirtualizationMode=“Recycling”
来提高性能。引自:

默认情况下,VirtualzingStackPanel为每个可见项创建一个项容器,并在不再需要它时(例如当该项从视图中滚出时)将其丢弃。当ItemsControl包含大量项时,创建和丢弃项容器的过程可能会对性能产生负面影响。当VirtualzingStackPanel.VirtualizationMode设置为Recycling时,VirtualzingStackPanel将重用项目容器,而不是每次创建一个新容器


内存泄漏可能在
Image
控件中。如果删除此项,您还会看到内存的大幅增长吗?当我填充列表框时,我会得到100MB的内存分配。如果从数据模板中删除映像,我会得到更少的内存分配,大约95MB。您大约有多少项?超过10000?可能您需要尝试
虚拟化StackPanel
虚拟化模式@安纳托利尼科拉耶夫工作得很好。我刚刚用
替换了我的
WrapPanel
,内存泄漏消失了。也许你应该发布你的答案以便接受它。非常感谢你。