2013-08-11 2 views
5

Ok У меня есть приложение WPF в Wich я создать свой собственный ListBoxItem в словаре ресурсов, который выглядит следующим образом:WPF ListboxItems Cosume слишком много памяти

<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 заполнит мой ListBox не менее чем 1000 StationItems.

Мой код работает нормально и начинается с памяти 40MB (Window Task Manager). Но всякий раз, когда я выбираю жанр и заполняю свою ListBox, память взрывается при 100 МБ. И затем я выбираю еще одну жанровую память. Я думал, что с ListBox.Items.Clear();ListBoxItems также будет уничтожен из памяти, но этого не произойдет.

Я попытался удалить изображение из своего ListoBoxItemTemplate и проверил память моего приложения, но не видел реальной разницы (разница в 4-7 МБ).

Так что мой ответ: Как я могу заставить приложение использовать намного меньше памяти при добавлении элементов в ListBox?

Спасибо заранее!

+0

Утечка памяти может быть в элементе управления 'Image'. Если вы удалите это, вы все равно увидите существенный рост памяти? –

+0

Когда я заполняю ListBox, я получаю выделение памяти 100 МБ. Если я удалю изображение из своего DataTemplate, я получаю немного меньше выделения памяти, около 95 МБ. – oimitro

+0

Сколько у вас предметов? более 10000? – ehsan88

ответ

2

Попробуйте использовать VirtualizingStackPanel.VirtualizationMode="Recycling" для улучшения производительности. Цитата MSDN:

По умолчанию VirtualizingStackPanel создает предмет контейнер для каждого видимого элемента и отбрасывает его, когда он больше не нужен (например, когда элемент прокручивается вне поля зрения). Когда элемент ItemsControl содержит много элементов, процесс создания и отбрасывания контейнеров элементов может отрицательно повлиять на производительность. Когда VirtualizingStackPanel.VirtualizationMode настроен на переработку, VirtualizationStackPanel повторно использует контейнеры элементов вместо создания нового.

Смежные вопросы