本文介绍了在分组的ListView中使用ItemTemplateSelector进行内存增长(泄漏?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ListView将其分组.这些项目由图标表示,这些图标由ItemTemplateSelector选择.随着时间的流逝,我的应用程序的内存使用量不断增长.我的处理方式有天生的错误吗?

XAML

I have a ListView which groups it's items. The items are represented by icons, which are chosen by an ItemTemplateSelector. Over time, memory usage of my application grows. Is there something inherently wrong with the way I am doing things?

XAML

<Window x:Class="MemoryLeak.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MemoryLeak"
    Title="Window1" Height="300" Width="300">
  <Window.Resources>
    <local:IconSelector x:Key="iconSelector"/>

    <DataTemplate x:Key="_GoodIcon">
      <Rectangle Fill="LightGreen" Width="16" Height="16" Stroke="Black" StrokeThickness="1"/>
    </DataTemplate>

    <DataTemplate x:Key="_BadIcon">
      <Rectangle Fill="LightPink" Width="16" Height="16" Stroke="Black" StrokeThickness="1"/>
    </DataTemplate>

    <DataTemplate x:Key="_IndifferentIcon">
      <Rectangle Fill="LightCoral" Width="16" Height="16" Stroke="Black" StrokeThickness="1"/>
    </DataTemplate>

  </Window.Resources>
  <ListBox x:Name="_List" 
           VirtualizingStackPanel.IsVirtualizing="False" 
           ItemTemplateSelector="{StaticResource iconSelector}">
    <ListBox.GroupStyle>
      <GroupStyle>
        <GroupStyle.ContainerStyle>
          <Style TargetType="{x:Type GroupItem}">
            <Setter Property="Template">
              <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                  <ItemsPresenter/>
                </ControlTemplate>
              </Setter.Value>
            </Setter>
          </Style>
        </GroupStyle.ContainerStyle>
      </GroupStyle>
    </ListBox.GroupStyle>
  </ListBox>
</Window>



C#



C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Threading;

namespace MemoryLeak
{
  public partial class Window1 : Window
  {
    List<Item> _Items = new List<Item>();
    public Window1()
    {
      InitializeComponent();
      for (int ix = 0; ix < 20; ix++)
      {
        _Items.Add(new Item() { Name = string.Format("Item {0}", ix + 1), Location = "Here" });
      }
      CollectionViewSource cvs = new CollectionViewSource();
      cvs.GroupDescriptions.Add(new PropertyGroupDescription() { PropertyName = "Location" });
      cvs.Source = _Items;
      _List.ItemsSource = cvs.View;
      DispatcherTimer dt = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(20) };
      dt.Tick += new EventHandler(dt_Tick);
      dt.Start();
    }

    public delegate void DispatchHandler();

    State currentState = State.Indifferent;
    void dt_Tick(object sender, EventArgs e)
    {
      currentState = (State)(((int)currentState + 1) % 3);
      IEditableCollectionView iecv = CollectionViewSource.GetDefaultView(_List.Items) as IEditableCollectionView;
      _Items.ForEach(i => { i.State = currentState; iecv.EditItem(i);  });
      iecv.CommitEdit();
    }
  }

  public enum State { Good, Bad, Indifferent };
  public class Item : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;
    PropertyChangedEventArgs e = new PropertyChangedEventArgs("State");
    State _State;
    public State State
    {
      get { return _State; }
      set
      {
        _State = value;
        if (PropertyChanged != null) PropertyChanged(this, e);
      }
    }
    public string Location { get; set; }
    public string Name { get; set; }
  }

  public class IconSelector : DataTemplateSelector
  {
    FrameworkElement _FeContext = null;
    Dictionary<State, DataTemplate> _IconTemplates = new Dictionary<State, DataTemplate>();
    void Init(FrameworkElement fe)
    {
      if (_FeContext == null && fe != null)
      {
        _IconTemplates[State.Good] = fe.FindResource("_GoodIcon") as DataTemplate;
        _IconTemplates[State.Bad] = fe.FindResource("_BadIcon") as DataTemplate;
        _IconTemplates[State.Indifferent] = fe.FindResource("_IndifferentIcon") as DataTemplate;
        _FeContext = fe;
      }
    }
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
      Init(container as FrameworkElement);
      DataTemplate dt;
      if (_IconTemplates.TryGetValue((item as Item).State, out dt))
      {
        return dt;
      }
      return base.SelectTemplate(item, container);
    }
  }
}

推荐答案


这篇关于在分组的ListView中使用ItemTemplateSelector进行内存增长(泄漏?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 05:34