Hi,
I have prepared minimal project to reproduce the issue.
The problem is when removing item from ObservableCollection<> binded to ItemsSource of ListView then the BindingContext of ViewCell is set for a while to the object being removed.
Run the project in Android emulator and when you click 'Remove' button then you can see in debug output this message about strange binding error:
[0:] Binding: 'Part' property not found on 'XamBugListView01.MainPage+ItemPart', target property: 'Xamarin.Forms.Label.BindingContext'
The project uses Xamarin.Forms 2.3.3.193.
Here is the source code of MainPage.xml.cs:
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Forms; namespace XamBugListView01 { public partial class MainPage : ContentPage { private ObservableCollection<Item> _allItems = new ObservableCollection<Item>(); public MainPage() { _allItems.Add(new Item()); _allItems.Add(new Item()); InitializeComponent(); _listView.BindingContext = new { AllItems = _allItems }; } private void RemoveClicked(object sender, EventArgs ea) { _allItems.RemoveAt(0); } public class Item { public ItemPart Part { get; private set; } public Item() { Part = new ItemPart(); } } public class ItemPart { private static int _counter; public string Name { get; private set; } public ItemPart() { Name = "item part " + (++_counter); } //public ItemPart Part //{ // get // { // throw new InvalidOperationException("Property Part of ItemPart is never used in any code and any XAML."); // } //} } } }
Here is the source code of MainPage.xml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:XamBugListView01" x:Class="XamBugListView01.MainPage"> <StackLayout Orientation="Vertical"> <ListView Grid.Row="1" x:Name="_listView" ItemsSource="{Binding Path=AllItems}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <Label BindingContext="{Binding Path=Part}" Text="{Binding Path=Name}" /> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> <Button Text="Remove" Clicked="RemoveClicked" /> </StackLayout> </ContentPage>
Everything else is generated from the template 'Blank Xaml App (Xamarin.Forms.Portable) C#' (project name is XamBugListView01).
Whole solution is attached in ZIP archive.
Hmm, this might be an issue in Forms. Can you file a bug report and attach your repro project so we can look into it? If this is a bug then we can use the report to track it. Thanks!
Answers
two errors
and
@AlessandroCaliaro
Ok, the first is error but it is not important to this problem. The binding to the BindingContext is on purpose because I use it in more complex code and this is only the MINIMAL code to reproduce the problem. Or it is forbidden to bind to the BindingContext?
Thanks for your time and your comment.
In ViewCell the BindingContext is already bind when you write (in listview)
I know. But image more complex situation. This is example: you want to display all animals in ZOO in ListView. Then you have these ViewModels for animal types (I will omit some details which are not important here like access rights and members of some classes):
And this ViewModel for real animals:
Then the MainPageViewModel looks like this:
There is custom user interface control to display different animal types in the project:
Then the ListView in the MainPageView.xaml is here:
In this example you can not avoid binding to BindingContext because it is nonsense to expect that the BindingContext's type of AnimalTypeView is AnimalViewModel type. Its type must be AnimalTypeViewModel. Do you agree?
Hmm, this might be an issue in Forms. Can you file a bug report and attach your repro project so we can look into it? If this is a bug then we can use the report to track it. Thanks!
Ok and thanks, I have submitted the report here:
https://bugzilla.xamarin.com/show_bug.cgi?id=53987