2013-08-11 36 views
5

Ok tôi đã một ứng dụng WPF trong Mà tôi tạo của riêng tôi ListBoxItem trong một cuốn từ điển tài nguyên đó trông như thế này:WPF ListBoxItems hoặt bộ nhớ quá nhiều

<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> 

Một ListBox như thế này:

 <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> 

Và tôi điền các mục ListBox của mình khi người dùng chọn một Thể loại của đài, với phương pháp như sau:

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); 
     } 
    } 

Lưu ý:Mỗi trạmGenre sẽ điền số ListBox của tôi với ít nhất 1000 StationItems.

Mã của tôi hoạt động tốt và bắt đầu bằng bộ nhớ 40MB (Trình quản lý tác vụ cửa sổ). Nhưng bất cứ khi nào tôi chọn một thể loại và điền vào bộ nhớ ListBox, phát nổ tại 100MB. Và sau đó tôi chọn một thể loại bộ nhớ khác phát nổ hơn nữa. Tôi nghĩ rằng với ListBox.Items.Clear(); các ListBoxItems sẽ bị phá hủy từ bộ nhớ quá, nhưng điều này không xảy ra.

Tôi đã cố xóa hình ảnh khỏi ListoBoxItemTemplate và kiểm tra bộ nhớ của ứng dụng nhưng không thấy sự khác biệt thực sự (Khoảng 4-7 MB khác biệt).

Vì vậy, câu trả lời của tôi là: Làm cách nào để ứng dụng của tôi tiêu thụ ít bộ nhớ hơn khi thêm các mục vào ListBox?

Cảm ơn trước !!

+0

Rò rỉ bộ nhớ có thể nằm trong điều khiển 'Hình ảnh'. Nếu bạn loại bỏ điều này bạn vẫn thấy bất kỳ sự tăng trưởng đáng kể trong bộ nhớ? –

+0

Khi tôi cư trú ListBox tôi nhận được một phân bổ bộ nhớ 100MB.Nếu tôi loại bỏ hình ảnh từ DataTemplate của tôi tôi nhận được một chút ít bộ nhớ phân bổ, khoảng 95 MB. – oimitro

+0

Có bao nhiêu mục bạn có? hơn 10000? – ehsan88

Trả lời

2

Hãy thử sử dụng VirtualizingStackPanel.VirtualizationMode="Recycling" để cải thiện hiệu suất. Trích dẫn từ MSDN:

Theo mặc định, VirtualizingStackPanel tạo mục chứa cho mỗi mục hiển thị và loại bỏ nó khi không còn cần thiết (chẳng hạn như khi mục được cuộn ra khỏi chế độ xem). Khi một ItemsControl chứa rất nhiều mục, quá trình tạo và loại bỏ các mục chứa có thể ảnh hưởng tiêu cực tới hiệu suất. Khi VirtualizingStackPanel.VirtualizationMode được đặt thành Recycling, VirtualizingStackPanel sẽ sử dụng lại các mục chứa thay vì tạo một vùng chứa mới mỗi lần.

Các vấn đề liên quan