I am developing an enterprise application using xamarin.forms. It has been few days ListView's Memory leak issue become a nightmare for me. For the sake of simplicity I'll try to explain with sample code.
XAML Page Code - Page with ListView and two Button(Add & Remove)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:ListViewTest" x:Class="ListViewTest.MainPage"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="10*" /> <RowDefinition Height="1*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <ListView Grid.Row="0" BackgroundColor="White" x:Name ="ItemsListView"> <ListView.ItemTemplate> <DataTemplate > <TextCell TextColor="Black" Text="{Binding ItemText}" DetailColor="Black" Detail="{Binding ItemDetail}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button Grid.Row="1" Text="Add" Clicked="AddItemClicked"/> <Button Grid.Row="2" Text="Remove" Clicked="RemoveItemClicked"/> </Grid> </ContentPage>
C# Code Behind - Just adding and removing objects from collection.
public partial class MainPage : ContentPage { ObservableCollection<SampleData> itemsListCollection; public MainPage() { InitializeComponent(); itemsListCollection = new ObservableCollection<SampleData>(); ItemsListView.ItemsSource = itemsListCollection; } void AddItemClicked(object sender, EventArgs e) { SampleData data = new SampleData(); data.ItemText = "An Item"; data.ItemDetail = "Item - " + (itemsListCollection.Count + 1).ToString(); itemsListCollection.Add(data); } void RemoveItemClicked(object sender, EventArgs e) { SampleData item = (SampleData)ItemsListView.SelectedItem; if (item != null) { itemsListCollection.Remove(item); } } }
Data class - Just two properties
class SampleData { public event PropertyChangedEventHandler PropertyChanged; private string itemText; public string ItemText { get { return itemText; } set { itemText = value; NotifyPropertyChanged("ItemText"); } } private string itemDetail; public string ItemDetail { get { return itemDetail; } set { itemDetail = value; NotifyPropertyChanged("ItemDetail"); } } private void NotifyPropertyChanged(string propName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propName)); } } }
Add Button - Adds item to ListView
Remove Button - Removes item from ListView
Problem -
1.) Add some items to list.
2.) Remove few or all.
3.) All previously added SampleData objects remain in memory even after all the items have been removed using Remove button.
Answers
Which platform?
@huangjinshe Windows. Though I have not checked on other platforms.
Only when add or remove Or when switch some pages and it contains a ListView?
@huangjinshe only When adding/removing and while using ListView as autocomplete.
I know ListView has a serious memory leak problem on UWP, but didn't thought even add item will cause it.
Please go to : Memory leak in Xamarin Forms ListView and download all sample and compare on your computer, If you think the latest solution good for you now, just take a time temporarily replace the ListView
Thanks very much for your efforts @huangjinshe , I don't want to use TemplateView Temporary solution. In my application I'm using ListView as a AutoComplete Control. Please help me to find the solution of this problem.
The sample code i posted in the question, i also checked it on WPF. It Works fine there - no memory leak in WPF.
Please try two another things:
@ionixjunior: Thank you for your note. Out of "3-platform" habit i forgot that. But second part should work.
@ionixjunior and @ComCon thanks very much for your replies,
@huangjinshe just want to let you know that the issue is only with XF version 2.2 or up. Memory is not leaking in 2.0 or 2.1.
The problem is, i have used a feature of XF 2.2, So i can't go back to lower version.
Also I have used the TemplateView temporary solution but how would i use ListView like events for e.g. Tapping a list view item, selecting an item etc.
Download and check the last sample, and you will see that. Maybe the only different is, you need to use custom renderer, let Button margin = 0(manually set not working in Xamarin.Forms, I tied before). Also set button BackgroundColor=Transparent. Just let user feel that'a a ListViewItem, but actually it's tapping a button.
Please upload a sample project, I'll check the source code for Xamarin.Forms when I have a free time, and would try to find a solution or fix.
Hi @huangjinshe, thanks for being so kind. I have completely replaced ListView with TemplateView in my project after a lot of code change
But i want to use ListView as TemplateView has many limitations. I'm sharing link of a sample project in which you can see the reproduced memory leak problem. Please help me to solve this problem/bug. Thanks a lot for your efforts and guidance.
Samle project link - https://drive.google.com/drive/folders/0B4m4sT494pRVS0o1M01rcDNTMk0?usp=sharing