Memory Leak sample using Listbox with Panel3D

Apr 24, 2009 at 10:09 PM
I am seeing a memory leak when adding and removing items from my ObservableCollection.
I am bound to the ItemsSource of the ListBox.
When I use Panel3D as the ItemsPanel I see the leak.
If I remove the ItemsPanel I get the default view and the leak is not there.

In my application I will have an image in my ControlTemplate that I want to display as it is feed to the program.

Can you let me know if there is something I should be doing to free up the memory after I
remove the item from my list and it is no longer bound to the ListBox using Panel3D.

I have created a small sample app with only integers that exhibits the leak.

SomeData.cs
//*******************************
namespace TestForLeak
{
    public class SomeData
    {
        public SomeData() { }

        public SomeData(int input)
        {
            _numberValue = input;
        }

        int _numberValue;
        public int DataValue
        {
            get { return _numberValue; }

            set { _numberValue = value; }
        }
    }
}

Window1.xaml.cs
//********************************
using System.Windows;
using System.Collections.ObjectModel;
using Thriple.Panels;
using System.Windows.Threading;
using System;

namespace TestForLeak
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        ObservableCollection<SomeData> _dataList;
        Panel3D _panel3D;
        DispatcherTimer dispatchTimer;
        int _runningCount;

        public Window1()
        {
            InitializeComponent();
            _runningCount = 0;

            _dataList = new ObservableCollection<SomeData>();

            dispatchTimer = new DispatcherTimer();
            dispatchTimer.Tick += new EventHandler(dispatchTimer_Tick);
            dispatchTimer.Interval = TimeSpan.FromSeconds(1);
            dispatchTimer.Start();

            _matchesListBox.ItemsSource = _dataList;
        }


        /// <summary>
        /// Update the current item
        /// </summary>
        void dispatchTimer_Tick(object sender, EventArgs e)
        {
            dispatchTimer.Stop();

            _dataList.Add(new SomeData(_runningCount++));

            // Only want to keep latest 5 in the list
            if (_dataList.Count > 5)
                _dataList.RemoveAt(0);


            dispatchTimer.Start();
        }

        private void OnPanel3DLoaded(object sender, RoutedEventArgs e)
        {
            // Grab a reference to the Panel3D when it loads.
            _panel3D = sender as Panel3D;
        }

    }
}

Window1.xaml
//********************************
<Window x:Class="TestForLeak.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:thriple="http://thriple.codeplex.com/"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ListBox x:Name="_matchesListBox"
                Focusable="False"
                IsSynchronizedWithCurrentItem="True"
                >
            <!--
        Tell the ItemsControl to use our custom
        3D layout panel to arrange its items.
      -->
            <!-- COMMENT OUT ITEMSPANEL AND LEAK GOES AWAY -->
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <thriple:Panel3D
                        AutoAdjustOpacity="False"
                        AllowTransparency="True"
                        ItemsHostLoaded="OnPanel3DLoaded"   
                        MaxVisibleModels="8" ItemLayoutDirection="-1,1.3,-7" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>

            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border BorderThickness="1" BorderBrush="Transparent">
                                    <Button Command="Open">
                                        <StackPanel>
                                            <TextBlock Text="{Binding DataValue}" ></TextBlock>
                                        </StackPanel>
                                    </Button>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</Window>
Coordinator
Apr 24, 2009 at 10:48 PM
Sorry to hear about this memory leak.  Unfortunately, I just returned my laptop with my memory profiler on it to my former employer.  I'll have to get another profiler before I can analyze this issue, but I will look into it.

Thanks,
Josh
May 31, 2009 at 7:11 PM

any ideas on solving this leak?