locked
ListView binding to ObservableCollection does not update GUI RRS feed

  • Question

  • User58544 posted

    Hi

    Can anyone tell me why this simple code is not working as expected? Does the ListView control not listen for changes in the bound property?

    • Expected: when I click the Add button, the GUI (ListView) updates through the binding and shows the new element in the ObservableCollection.
    • Observed: GUI does not update but always shows the initial three items of the ObservableCollection.
    • Btw: OnAddButtonClicked() does get called and ListViewItems does get updated (checked in the debugger). Calling OnPropertyChanged("ListViewItems") inside OnAddButtonClicked() did not help either.
    • And: if I update the code as follows, the ListView works: add a Label control, bind that label to a 2nd property, update that property inside OnAddButtonClicked(), call OnPropertyChanged() from inside the property setter. So obviously this call to OnPropertyChanged() somehow triggers the ListView to get updated as well...
    • I'm now using Xamarin.Forms version 1.1.0.6201. Didn't work with the previous version either.

    XAML:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Test1.MainPage"
                 Padding="10" Title="MainPageXaml">
        <StackLayout VerticalOptions="StartAndExpand" HorizontalOptions="Fill">
            <Button Text="Add" Clicked="OnAddButtonClicked" />
            <ListView ItemsSource="{Binding ListViewItems}" />
        </StackLayout>
    </ContentPage>
    

    C#:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            ListViewItems = new ObservableCollection<string> { "one", "two", "three" };
            BindingContext = this;
        }
    
        private void OnAddButtonClicked(object sender, EventArgs e)
        {
            ListViewItems.Add(DateTime.Now.ToString());
            // OnPropertyChanged("ListViewItems");
        }
    
        public ObservableCollection<string> ListViewItems { get; set; }
    }
    

    Markus

    Tuesday, June 17, 2014 1:03 PM

All replies

  • User33 posted

    This should work. Which platform(s) have you tried on?

    Tuesday, June 17, 2014 4:04 PM
  • User58544 posted

    This:

    • Visual Studio 2013 Update 2
    • Xamarin 3.0.54.0, Xamarin.Android 4.12.4.20 (as shown in VS), evaluation licence
    • Xamarin.Forms 1.1.0.6201
    • Xamarin.Android.Support.v4 19.0.2
    • "standard" new project -> Mobile Apps -> Xamarin.Forms Portable ** only change done by me: disabled fast deployment (didn't work with Samsung Note 2)
    • Windows 8.1 Update 1 64bit
    • JDK 1.6.0_45
      • btw: why not JDK 8, or at least JDK 7? 1.6 is not even easily downloadable anymore and full of bugs
    • all the Android SDK's that Xamarin downloaded ("many": 4.0.3, 3.1, 2.2.3, 2.2, 2.1) over the one I've already had installed from Android SDK (SDK Tools 22.6.4; SDK Platform 4.4.2 ~ API 19, rev 3)
      • -> btw: couldn't you reduce the number of required Android SDK's? I mean: version 2 & 3 ....
    • tests on Samsung Note 2 (GT-N7105), Android 4.3, more or less using factory defaults, no SIM card, has WLAN
    Wednesday, June 18, 2014 6:14 AM
  • User58544 posted

    Another update: I found the following errors message in the Android Device Logging (open via View -> Other -> Android Device Logging):

    DatabaseUtils: Writing exception to parcel
    DatabaseUtils: java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
    ... (stack trace)
    ActivityManager: Permission Denial: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
    

    (btw: why can't I copy-paste from the Android Device Logging window? this is really annoying)

    My first thought was that this might be caused by the "Use Shared Runtime" option. So I tried without a shared runtime. Same resultes. I also tried adding the INTERACTACROSSUSERS_FULL permission, but that didn't work either (and I think it's not possible to request that permission by an app anyway).

    Wednesday, June 18, 2014 6:49 AM
  • User3932 posted

    @mkvonarx, did you check if you can scroll to the added item? There is an issue where the listview bounds are not updated, although the item IS added (but just not visible). I have this type of code working fine...

    Wednesday, June 18, 2014 6:58 AM
  • User58544 posted

    @HugoLogmans, I just checked and you're right: the items are added to the ListView, but the ListView bounds are unchanged and the new items are therefore not visible. So issue solved, or at least relegated to a layouting problem. Thanks!

    Wednesday, June 18, 2014 7:44 AM
  • User59376 posted

    Hi @mkvonarx? , How did you resolve this problem? I get the same problem. After reloading the observationcollection datasource, nothing change but if I rotate the device the listview update and show the items correctly

    Tuesday, July 22, 2014 7:40 AM
  • User58544 posted

    Hi @maidinhnga? Well... My first workaround was to manually set the size of the ListView control. But finally I completely gave up on Xamarin.Forms and went back to using native Android AXML for the Android GUIs because Xamarin.Forms is just not mature (feature rich, bug free) enough for my needs, e.g. I couldn't even set the font size on some controls. Markus

    Thursday, July 24, 2014 7:21 AM
  • User46324 posted

    Any idea how this would work? Is there a way to force the list to reload data/render again. For me this problem repro on WP not on iOS

    Friday, July 25, 2014 1:55 AM
  • User37816 posted

    Just ran into this bug as well. Any news on a possible fix?

    Tuesday, August 26, 2014 2:08 PM
  • User19453 posted

    Yep, it's extremely annoying -- ListViews + ObservableCollections are used everywhere. It'd be great to have an ETA for the fix... (i can repro it on iOS).

    Monday, September 1, 2014 10:43 AM
  • User59890 posted

    The work around is to encapsulate the list inside a grid with a row height of '*'

    Monday, September 8, 2014 12:59 PM
  • User73234 posted

    Is there a fix for this anytime soon? I am evaluating the product and have been fairly impressed so far although this is a real nightmare for a Xamarin novice. Can someone post the code for work around. I am running the latest codebase.

    Thanks in advance.

    Monday, September 8, 2014 8:45 PM
  • User54051 posted

    @RobCrabtree? Could you elaborate?

    Monday, September 8, 2014 11:57 PM
  • User59890 posted

    @Kyle?, This solves the problem, notice the _RowDefinition _with a height of '*'. This instructs the row to consume the remaining space, this list then fills the row. Without this the height of the list has to be manually controlled. Let us know if this solves your problem.

    <Grid>
        <Grid.RowDefinitions>
          <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <ListView  ItemsSource="{Binding Path=MyItems}" HasUnevenRows="True"  >
          <ListView.ItemTemplate>
            <DataTemplate>
              <ViewCell>
                <ViewCell.View>
                  <StackLayout>
                    <Label Text="{Binding Line1}"  />
                    <Label Text="{Binding Line2}"  />
                  </StackLayout>
                </ViewCell.View>
              </ViewCell>
            </DataTemplate>
          </ListView.ItemTemplate>
        </ListView>
      </Grid>
    
    Tuesday, September 9, 2014 7:09 AM
  • User57631 posted

    @Kyle? Your solution works :)

    Thursday, September 11, 2014 7:47 AM
  • User18207 posted

    This is really frustrating. Everything I need to do requires some sort of fix and some of these fixes aren't compatible it seems. Such a huge step forward to use Forms but such an absolute mission to get working :(

    Wednesday, September 24, 2014 2:38 PM
  • User18207 posted

    @Kyle thanks mate, you got me partially there. GridUnitType.Star didn't work, but just using Grid in general seems to work.

    I couldn't use GridUnitType.Star just like you described because the other StackLayouts didn't adjust accordingly and I ended up with what I presume to be controls overlapping, effectively not showing the buttons I needed to show to add rows into my ListView.

    After re-factoring, just using Grid as a container with a fixed height, I could test and confirm. For the test my container grid is defined as:

    Grid grid = new Grid();
    grid.RowDefinitions.Add(new RowDefinition() { Height = page.Height - 200 });            
    grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) });
    

    I had to subtract 200 from the page height because for the moment I can't get my layouts to play together in the sand pit, they keep fighting.

    Wednesday, September 24, 2014 3:12 PM
  • User39930 posted

    I have a similar scenario. ListView doesn't update (even when wrapped in a grid). However, tapping a toggle switch in the same view miraculously updates the UI. Seems like some kind of render refresh issue.

    Thursday, October 23, 2014 1:10 PM
  • User85989 posted

    Had a similar issue with a TabbedPage containing ContentPages with ListViews. Lists were empty unless I rotated to landscape to enforce a layout update. A workaround was to add UpdateChildrenLayout(); in PageChanged event handler.

    It's worth noting that I have this issue only when wrapping the TabbedPage inside NavigationPage.

    Tuesday, November 11, 2014 9:47 AM
  • User84271 posted

    @ermau? It seems a lot of people have this bug; do you know if it was ever fixed? I'm running into the same problem.

    Monday, December 22, 2014 9:34 PM
  • User10864 posted

    I also have the same problem. Anyone know when it will be fixed? I'm using code to build my UI instead of XAML. I explicitly reset the ItemsSource, but it makes no difference. Other views update correctly, but the ListView does not.

    Monday, January 5, 2015 5:00 AM
  • User96208 posted

    Why doesn't some Xamarin employee monitor the forums? Do they care? The support that I see on this product is m.i.a. Man, this should be an easy bug to fix on their side.

    Thursday, January 8, 2015 4:33 AM
  • User90487 posted

    Same as you guys... TabbedPage + ListView + ObservableCollection = nightmare ... i'm sending a message to updatelayout eachtime i load the datasource. It's better but still have some empty list while everything isn't empty ...

    Monday, January 12, 2015 3:56 PM
  • User2773 posted

    TabbedPage + ListView has also problem with ListView.ScrollTo method (it doesn't work every time on Android)

    Monday, January 12, 2015 4:20 PM
  • User73114 posted

    I've developed XAML+C# for Silverlight for years. Took me a while to get this working though. My solution was an old trick to clear the ListView.ItemsSource completely whenever CollectionChanged occured on the source collection. UpdateLayout didn't help.

    In my ContentView I have a control named ListViewItems as well as the BindableProperty this.ItemsSource (write those with a nice ReSharper template!) to initially supply the source collection.

    When I get the collection I start listening to CollectionChanged:

            private static void ItemsSourceChanged(BindableObject bindable, IEnumerable oldValue, IEnumerable newValue)
            {
                var hliListBox = ((HliListBox)bindable);
                hliListBox.ListViewItems.ItemsSource = newValue;
                var obs = newValue as INotifyCollectionChanged;
                if (obs != null)
                {
                    obs.CollectionChanged -= hliListBox.Update;
                    obs.CollectionChanged += hliListBox.Update;
                }
            }
    

    The Update method then flushes the ListView's source and re-sets it.

            private void Update(object sender, NotifyCollectionChangedEventArgs e)
            {
                this.Update();
            }
    
            private void Update()
            {
                var src = this.ItemsSource;
                this.ItemsSource = null;
                this.ListViewItems.ItemsSource = null;
                this.ItemsSource = src;
                this.ListViewItems.ItemsSource = this.ItemsSource;
            }
    

    I might be crazy but can't get the thing to work otherwise. This is a Xamarin Forms 1.3 PCL project.

    Monday, January 12, 2015 10:02 PM
  • User48215 posted

    Just encountered this problem, It happens when creating(declaring through XAML in my case) a Custom ContentView that contains the ListView Object more than once. Xamarin only updates the last created ListView Object.

    Solved it by creating new ContentView instead of reusing the existing one.

    Friday, January 16, 2015 2:57 PM
  • User100404 posted

    I've reproduced the problem in simple form here

    Friday, January 23, 2015 6:43 PM
  • User2148 posted

    There is a solution to this problem?

    Monday, January 26, 2015 1:12 PM
  • User904 posted

    It's sounds like a bug in Xamarin.Forms, I have already filed it on Bugzilla here: https://bugzilla.xamarin.com/show_bug.cgi?id=26418, it will be easy for you guys to track it.

    If you add yourself to the CC list in that bug report, you'll automatically be emailed whenever the report is updated; including any workarounds that our engineers find in the process of working on the bug.

    Monday, January 26, 2015 2:53 PM
  • User100404 posted

    I suspect this may be the same issue as Bug 23585, Reported: 2014-10-03

    Monday, January 26, 2015 8:48 PM
  • User10864 posted

    I think there are actually two issues. I solved the updating problem by explicitly resetting ItemSource like @ThomasHagstrm does, but there was another issue also: I noticed that the list remains empty when I start adding items one at a time. This is on Android BTW, I haven't tested iOS.

    I then found that the items appear when I touch the list. The problem seems to be that the items are scrolled out of view. Of course ScrollTo does not actually seem to work. :-(

    Friday, January 30, 2015 12:56 AM
  • User73114 posted

    Have anyone reported this in Xamarin's bugzilla?

    Friday, January 30, 2015 10:17 AM
  • User2148 posted

    Is it been resolved?

    Saturday, February 7, 2015 5:20 PM
  • User97322 posted

    Try Adding... ViewModel.Dashboards.CollectionChanged += Dashboards_CollectionChanged;

    It will only trigger only if the collection changes, not individual properties. To workaround this, try clearing the collection then adding items one-by-one.

    If I just set the collection after clearing it doesn't trigger.

    It works but its not optimal. Anyone has another idea?

    Wednesday, April 15, 2015 7:23 PM
  • User125713 posted

    Hi - any updates on this bug?

    Tuesday, May 19, 2015 8:09 PM
  • User83484 posted

    Same here, hours lost due to this... any fix planned after 6 months when bug is known and provided to Xamarin devs?

    Wednesday, May 20, 2015 10:10 PM
  • User129607 posted

    Hi,

    in the bug https://bugzilla.xamarin.com/show_bug.cgi?id=26418 Jason Smith wrote on 2015-05-21 it shall be fixed in the next release. But what version is this and when did we get this?

    greetings

    Monday, June 8, 2015 8:36 AM
  • User42522 posted

    @Latzi The Xamarin.Forms version 1.4.4 was released on July 27, 2015 and this is the latest. Did you check if it is resolved.

    Also, has anyone tried placing the ListView in a ScrollView?

    I had similar issue as changes to an ObservableCollection doesn't update the ListView. I had no issue with adding an item but when an item is modified or deleted the ListView doesn't refresh.

    Item Update:

    1. I delete the item and insert it at the same point.
    2. In WP no issue.
    3. In Android, I have to do it in the "Save" action method.
    4. In iOS, I have to do it in the OnAppearing() override in the page where the ListView is residing.

    Item Delete: I am still working on it. The item is deleted from the collection but the ListView is not reflecting it. The app has to be restarted to see that the item is deleted. But one more issue with iOS is that when you exit the app by pressing the Home button, the app is actually in the suspended state and a snapshot of the current page is saved. So when you restart the app, the last snapshot stored is displayed. You will have to actually kill the app by swiping in the suspended app list and restart the app.

    Tuesday, September 1, 2015 6:07 PM
  • User156010 posted

    I tried 1.4.4 and it's still a problem. Only tried on Android. My work around is to add and remove a temporary item, this way I don't mess with the real data.

    Friday, September 4, 2015 4:41 PM
  • User139205 posted

    As mentionned by @RobCrabtree fixing the height of the Grid to * works. But the ListView should have the HasUnevenRows="true", if the RowHeight is set it's not working.

    Tuesday, November 24, 2015 8:54 AM
  • User117013 posted

    This is not a bug, folks. You have to understand how binding works...

    When InitializeComponent() is called in the constructor, your XAML is loaded and all controls are initialized. At that time your listview gets it value from ListViewItems property, which happens to be null. So, nothing displays.

    After that, in the constructor, you are setting your ListViewItems property but that does not mean your listview automatically gets the value. You have to tell it by raising a PropertyChanged event. Only then it will get the new value. Change your code to the following to make it work:

    public MainPage() { BindingContext = this; InitializeComponent(); ListViewItems = new ObservableCollection { "one", "two", "three" }; }

    private ObservableCollection listItems; public ObservableCollection ListViewItems { get { return listItems; } set { listItems = value; OnPropertyChanged(nameof(ListViewItems)); } }

    Alternately, do just this which sets up the items before InitializeComponents() is called. Of course, this assumes the collection instance will not be changed subsequently. Otherwise, you'll have to use the code above.

    public MainPage() { BindingContext = this; ListViewItems = new ObservableCollection { "one", "two", "three" }; InitializeComponent(); }

    Fyi, the listview is monitoring for a PropertyChanged event from the container of the property it is bound to. In this case, the container is your MainPage. It's good practice if changing value of public properties, raise the PropertyChanged event.

    You might then ask what's the use of an ObservableCollection. Well, the collection itself raises a CollectionChanged event if its collection changes. So, in either implementation shown above you can add, remove, move, clear its contents, and your listview control will know and will update the display accordingly. That's what the "observable" part of the name implies :smile:

    Hope this helps. JP

    Tuesday, December 15, 2015 7:29 AM
  • User107708 posted

    Hi,

    I have strange issue with mvvm binding. Once viewmodel property changed it not reflecting on UI part. I tried with Device.BeginInvokeOnMainThread(()=> ...); . But still problem...

    Let me know how can handle this situation..

    Sunday, January 3, 2016 3:35 AM
  • User76916 posted

    @Anee - please don't post the same question in 3 old threads. Post a single new Question in the relevant forum and community members will be there to help you out if you provide a good description of what the issue is.

    Sunday, January 3, 2016 3:44 AM
  • User107708 posted

    @AdamP . Maybe its an old question the solution is not working on my scenario . ...

    Sunday, January 3, 2016 5:49 AM
  • User76916 posted

    @Anee exactly, you have a new scenario. Please post a new question with your explicit scenario, otherwise threads get convoluted. We can then focus on your scenario. Feel free to post a link back to this thread though if appropriate.

    Sunday, January 3, 2016 6:08 AM
  • User182167 posted
        Binding _isBusyBinding;
    

    it gives warning as private field _isBusyBinding is assigned, but never used. can anyone suggest me ways to resolve this warning.!

    Wednesday, February 24, 2016 9:31 AM
  • User122717 posted

    @JashPatel, make sure you're talking about the same thing. What people report as a bug is that adding items to the list at run-time doesn't seem to update the list. I've worked with xaml/wpf since it came out and never experienced any problem with the ListView/ObservableCollection on Windows.

    Guess what a surprise it was to discover that this bug still exist in Xamarin Forms almost two years after it was reported here. I'm using Xamarin Studio Version 5.10.3 (build 27) with Mono 4.2.3 on a MacBook Pro and I'm developing for iOS. It would be so nice if the Xamarin dev. team could fix this bug soon, because for an "old" wpf programmer this is rather annoying to say the least.

    Sunday, March 20, 2016 3:21 PM
  • User117013 posted

    @norgie, I respectfully disagree. If this "bug" has been in existence for 2 years, you should see a lot more complaints. I use Xamarin to develop Android and iOS apps. I use ObservableCollection extensively, and it's been working fine for me.

    As I pointed out my my previous post, in order to notify your UI when the "ListViewItems" properties is set you must raise the PropertyChanged event. Otherwise, the UI won't know about it; thus adding/deleting/removing items in the collection does nothing in the UI.

    Once the event is raise and the UI retrieves the property, it will monitor CollectionChanged event in the OvservableCollection.

    Sunday, March 20, 2016 10:55 PM
  • User76049 posted

    I remember the original bug but I've had no issues in iOS or Android with ObservableCollection binding for ages.

    I'm using VS2013 and Win10 and a Mini Mac for compiling iOS.

    Monday, March 21, 2016 12:50 PM
  • User122717 posted

    @JashPatel The following code is from a WPF project:

    <ListView ItemsSource="{Binding Source={StaticResource MessagesViewSource}}"> <ListView.ItemTemplate> <DataTemplate DataType="{x:Type Common:StatusMessage}"> <StackPanel Orientation="Horizontal" Margin="10,2"> <StackPanel.Resources> <Style TargetType="TextBlock"> <Style.Triggers> <DataTrigger Binding="{Binding Type}" Value="{x:Static Common:StatusType.Failure}"> <Setter Property="Foreground" Value="Red" /> </DataTrigger> </Style.Triggers> </Style> </StackPanel.Resources> <TextBlock Text="{Binding Time, StringFormat=t}" /> <TextBlock Text="{Binding Text}" Margin="10, 0, 0, 0" /> </StackPanel> </DataTemplate> </ListView.ItemTemplate> </ListView> The collection:

    public ObservableCollection<StatusMessage> Messages { get; private set; }

    In the ViewModel's constructor:

    Messages = new ObservableCollection<StatusMessage>();

    Updating the observable collection: public void Handle(StatusInfoChanged message) { Messages.Add(message.StatusMessage); if(message.StatusMessage.Type == StatusType.Failure) StatusMessageArrived(this, EventArgs.Empty); } There is no, I repeat, no notification code here and this works right out of the box. Maybe you don't think this is a bug on Xamarin's part, but in my book it is because WPF was there long before Xamarin Forms.

    I guess we'll have to agree to disagree on this one.

    Monday, March 21, 2016 9:33 PM
  • User186778 posted

    @JashPatel said: This is not a bug, folks. You have to understand how binding works...

    When InitializeComponent() is called in the constructor, your XAML is loaded and all controls are initialized. At that time your listview gets it value from ListViewItems property, which happens to be null. So, nothing displays.

    Exactly that. Thank you for explaining this non-issue.

    Xamarin.Forms really could use an in-depth guide on data binding.

    Wednesday, May 4, 2016 9:40 AM
  • User76049 posted

    @HermannScharitzer

    Check out chapter 16 of this great ebook.

    https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/

    Wednesday, May 4, 2016 10:24 AM
  • User186778 posted

    @NMackay said: @HermannScharitzer

    Check out chapter 16 of this great ebook.

    https://developer.xamarin.com/guides/xamarin-forms/creating-mobile-apps-xamarin-forms/

    Already got my eye on it! I know Charles Petzold back from win32 API coding. Was rightfully called the windows API bible.

    Wednesday, May 4, 2016 10:33 AM
  • User76049 posted

    @HermannScharitzer

    Caught his talk at Evolve and got a signed copy of his book.

    Wednesday, May 4, 2016 11:01 AM
  • User217165 posted

    guys i've implement a sample here which i'm using OnPropertyChanged to bind my control to other control but couldn't make it in the normal list it doesn't get notifier so when i changed it to ObservableCollection it works but what's wrong here why the list didn't get notified when i implement my interface ?

    Thursday, June 2, 2016 9:38 AM
  • User46691 posted

    This is still an issue...

    Wednesday, June 15, 2016 2:09 PM
  • User217165 posted

    one of my friend helped me out attached you can find a sample , what we had to do is to implement the OnPropertyChanged on the models of the list it self

    Wednesday, June 22, 2016 2:02 AM
  • User77854 posted

    Hi I've skimmed through the posts, but I had a similar problem.

    I wanted to simply bind a ObservableCollection class list of a custom class to a ListView container.

    I followed the two tutorials (Introduction to Xamarin.Forms and ListView Data Source) and I could see that the number of items in the list displayed were correct, but the binding data content wasn't displaying on the device.

    The trick that did it for me was setting the getter/setters for the custom class members. Here's the code that worked for me:

    My custom Page class Member varible and class declaration `

        // Create a class which will hold the itmes
        public class ListItem
        {
            // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!!
            public string VideoTitle { get; set; }
            public string URL {get;set;}
            public string VideoID {get;set;}
        }
    
        // Create a list as a memeber.
        // This list will be "bounded" to the ListView container
        // also needs the statement uptop: " using System.Collections.ObjectModel; "
        ObservableCollection<ListItem> content_list = new ObservableCollection<ListItem>();
    

    `

    `

    public VideoListPage() { InitializeComponent();

            // Populate the list 
            content_list.Add(new ListItem { VideoTitle = "Test", URL = "https://www.google.co.uk/", VideoID = "1" });
            content_list.Add(new ListItem { VideoTitle = "Meh", URL = "https://www.google.co.uk/", VideoID = "2" });
            content_list.Add(new ListItem { VideoTitle = "Moo", URL = "https://www.google.co.uk/", VideoID = "3" });
    
            // ---  "Bind" the list to the ListView container. ---
            // In the .XAML file we know it's called ' x:Name="ContentList" '
    
            // First we assign the list of <ListItem> class to the ListView container
            ContentList.ItemsSource = content_list;
    
            // --- End of Binding --- //
    
            // Becauset the ObservableCollection class is bounded to the ListView, we can ammend the list after assigning
            // the current list, and the ListView container will AUTOMATICALLY update 
            content_list.Add(new ListItem() { VideoTitle = "New Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });
            content_list.Add(new ListItem() { VideoTitle = "Second Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });      
        }
    }
    

    `

    And the corresponding XAML

    <ListView x:Name="ContentList"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text ="{Binding VideoTitle}" /> </DataTemplate> </ListView.ItemTemplate>
    </ListView>

    I hope this helps :) (p.s. I think this is my first post! woo)

    Wednesday, June 22, 2016 12:25 PM
  • User77854 posted

    Hi I had a similar problem and I had reached a solution.

    All I wanted to do was to bind an ObservableCollection class to a ListView, much like the tutorial on Xamarin website suggests. But somehow the APP deployed showed blank items, even though the number of items in the ListView were correct -- which suggested to me that its still a data binding problem.

    Another post somewhere suggested a layout problem, but what saved the day for me was placing the getters and setters for the custom class members which I wanted to bind to.

    // Create a class which will hold the itmes public class ListItem { // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!! public string VideoTitle { get; set; } public string URL {get;set;} public string VideoID {get;set;} }

    My almost full CS code implementation was this:

    `public partial class VideoListPage : ContentPage { // Create a class which will hold the itmes public class ListItem { // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!! public string VideoTitle { get; set; } public string URL {get;set;} public string VideoID {get;set;} }

        // Create a list as a memeber.
        // This list will be "bounded" to the ListView container
        // also needs the statement uptop: " using System.Collections.ObjectModel; "
        ObservableCollection<ListItem> content_list = new ObservableCollection<ListItem>();
    
        public VideoListPage()
        {
            InitializeComponent();
    
            // Populate the list 
            content_list.Add(new ListItem { VideoTitle = "Test", URL = "https://www.google.co.uk/", VideoID = "1" });
            content_list.Add(new ListItem { VideoTitle = "Meh", URL = "https://www.google.co.uk/", VideoID = "2" });
            content_list.Add(new ListItem { VideoTitle = "Moo", URL = "https://www.google.co.uk/", VideoID = "3" });
    
            // ---  "Bind" the list to the ListView container. ---
            // In the .XAML file we know it's called ' x:Name="ContentList" '
    
            // We assign the list of <ListItem> class to the ListView container
            ContentList.ItemsSource = content_list;
    
            // --- End of Binding --- //
    
            // Because the ObservableCollection class is now bounded to the ListView, we can ammend the list after assigning
            // the current list, and the ListView container will AUTOMATICALLY update 
            content_list.Add(new ListItem() { VideoTitle = "New Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });
            content_list.Add(new ListItem() { VideoTitle = "Second Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });      
        }
    }`
    

    And the corresponding XAML code

    <ListView x:Name="ContentList"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text ="{Binding VideoTitle}" /> </DataTemplate> </ListView.ItemTemplate>
    </ListView>

    I hope this helps. Also my first post! (I think?) OK I can't seem to get the code snippet showing well on this comment, so I appologise for that.

    Wednesday, June 22, 2016 12:41 PM
  • User65040 posted

    This is a rather crude solution. You don't need an ObservableCollection, if you first populate the collection and then assign it as items source. This can also be achived with a List or even an IEnumerable.

    I often see certain dependency objects confused these times: items and collections.

    If you use an ObservableCollection it's all about INotifyCollectionChanged. For binding the items of a collection, you have to implement INotifyPropertyChanged.

    public class ListItem : INotifyPropertyChanged
    {
        // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!!
        // public string VideoTitle { get; set; } <-- this doesn't bind as dependency object as well!
    
        // this really binds your data model to the list view, meaning: if you 
        // change the VideoTitle of an item, it will actually update your view!
        private string videoTitle;
        public string VideoTitle
        {
            get
            {
                return videoTitle;
            }
            set
            {
                if (value != VideoTitle)
                {
                    videoTitle = value;
                    OnPropertyChanged();
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    
        void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    INotifyCollectionChanged is easier to use because you usually won't have to add a handler to your collection: You rather would want to use a readily available INotifyCollectionChanged implementation of List<> called ObservableCollection.

    Thursday, June 23, 2016 10:56 AM
  • User218508 posted

    Try setting RowHeight to 1, even if you like me use HasUnevenRows to true ...

    This fixed the problem on Android for me.

    And dudes ... stop saying this is not a bug. Xamarin is a Cross Platform framework, if something works differently between platforms that's a bug for sure.

    Friday, June 24, 2016 1:18 PM
  • User125363 posted

    In my case my project is using MVVMLight with an IOC container, the IoC container doesn't set the BindingContext until after the page has been constructed, but the constructor was calling InitializeComponent as though it was.

    I guess InitializeComponent was binding my UI ListView (defined in the XAML) to a binding that didn't exist in the BindingContext yet!

    Even though the binding was set later by the IoC container, Xamarin.Forms didn't render changes to the list, although it did handle all the other simple bindings (i.e. Strings in the model to Labels in the UI).

    I did try to invoke InitializeComponent whenever the model changed, but this seemed inefficient.

    To work around this I modified the code-behind for the .xaml to defer calling InitalizeComponent until the BindingContext was explicitly set by the IoC container (by overriding the OnBindingContextChanged method) ...

        using System;
        using System.Collections.Generic;
        using PubSub;
        using Xamarin.Forms;
    
        namespace Presentation
        {
            public partial class MyPage : BasePage
            {
                public MyPage ()
                {
                    // NOTE - Do not call InitializeComponent in here - the main model is not injected yet and will cause
                    // the Xamarin.Forms list to not render the List, worse still if I add entities to my collecion the
                    // list does not update!
                }
    
                protected override void OnBindingContextChanged ()
                {
                    base.OnBindingContextChanged ();
                    InitializeComponent ();
                }
    
           }
        }
    

    Hopefully this will help someone out that has a similar initialisation lifecycle.

    Sunday, July 3, 2016 11:23 PM
  • User65040 posted

    It just doesn't seem right. If you have to do this, there is a fundamental flaw in you code.

    Monday, July 4, 2016 10:46 AM
  • User125363 posted

    Unfortunately the code was inherited and the lifecycle isn't 'typical' (it uses MvvmLite and a factory that creates the Views and Models, it creates the view first then sets the model afterwards - not in the constructor) - I'm just sharing this in case it helps someone else.

    Monday, July 4, 2016 10:54 AM
  • User65040 posted

    Creating the model separately from the view can be troublesome. But this is just wrong and maybe only helps in your special case, possibly perpetuating a bug that might pop up at some other point in the future.

    Maybe you want to deliver some context? Model, collection, and how its been populated with data, so we can learn?

    Monday, July 4, 2016 11:05 AM
  • User248956 posted

    @Oliver.4228 said: Hi I've skimmed through the posts, but I had a similar problem.

    I wanted to simply bind a ObservableCollection class list of a custom class to a ListView container.

    I followed the two tutorials (Introduction to Xamarin.Forms and ListView Data Source) and I could see that the number of items in the list displayed were correct, but the binding data content wasn't displaying on the device.

    The trick that did it for me was setting the getter/setters for the custom class members. Here's the code that worked for me:

    My custom Page class Member varible and class declaration `

        // Create a class which will hold the itmes
        public class ListItem
        {
            // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!!
            public string VideoTitle { get; set; }
            public string URL {get;set;}
            public string VideoID {get;set;}
        }
    
        // Create a list as a memeber.
        // This list will be "bounded" to the ListView container
        // also needs the statement uptop: " using System.Collections.ObjectModel; "
        ObservableCollection<ListItem> content_list = new ObservableCollection<ListItem>();
    

    `

    `

    public VideoListPage() { InitializeComponent();

            // Populate the list 
            content_list.Add(new ListItem { VideoTitle = "Test", URL = "https://www.google.co.uk/", VideoID = "1" });
            content_list.Add(new ListItem { VideoTitle = "Meh", URL = "https://www.google.co.uk/", VideoID = "2" });
            content_list.Add(new ListItem { VideoTitle = "Moo", URL = "https://www.google.co.uk/", VideoID = "3" });
    
            // ---  "Bind" the list to the ListView container. ---
            // In the .XAML file we know it's called ' x:Name="ContentList" '
    
            // First we assign the list of <ListItem> class to the ListView container
            ContentList.ItemsSource = content_list;
    
            // --- End of Binding --- //
    
            // Becauset the ObservableCollection class is bounded to the ListView, we can ammend the list after assigning
            // the current list, and the ListView container will AUTOMATICALLY update 
            content_list.Add(new ListItem() { VideoTitle = "New Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });
            content_list.Add(new ListItem() { VideoTitle = "Second Item added after list binding", URL = "https://www.google.co.uk/", VideoID = "3" });      
        }
    }
    

    `

    And the corresponding XAML

    <ListView x:Name="ContentList"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text ="{Binding VideoTitle}" /> </DataTemplate> </ListView.ItemTemplate>
    </ListView>

    I hope this helps :) (p.s. I think this is my first post! woo)

    As @Oliver.4228 said this was my EXACT issue: // public string VideoTitle; <<<< !!!!! ------- THIS DID NOT BIND WELL ----- !!!!

            public string VideoTitle { get; set; }
            public string URL {get;set;}
            public string VideoID {get;set;} 
    
    Thursday, August 11, 2016 3:38 PM
  • User2148 posted

    I don't use xaml... This is a little sample that demonstrate that observablecollection works with listview in XF https://github.com/acaliaro/TestBindingWithListView

    Thursday, August 11, 2016 7:33 PM
  • User244070 posted

    My solution is to add something like this after you add items to the observable collection

    ListOfPeople.Add(NewPerson); PeopleList.MinimumHeightRequest = ListOfPeople.Count > 0 ? 0 : 200; // Forces empty list to redraw since it starts off with 0 height, otherwise you think its not drawing the new items the first time around when in fact it is

    Tuesday, August 16, 2016 8:50 PM
  • User264645 posted

    Hi everyone, I've some issues with the listview refresh. I try to explain:

    I have a listview which load data when appearing, using observable collection and binding item source. Scrolling the list, when the scroll stop, a timer start for three second that read and load data from database and update visible items of the listview.

    ListaArticoli is the listview itemsource:

                try
                {
                    foreach (PrezzoListino elem in cp.prezzi)
                    {
                        ListaArticoli[elem.index].LI00_PREZZOLISTINO = elem.prezzo;
                    }
                }
                catch (Exception ex)
                {
    
                }
    

    the itemsource is updated but the data will not show loaded data.. in fact, scrolling down and up (caming back to the updated items) the item appear correct (the listview is refreshed).

    Could anyone tell me any solution or idea?

    Thanks in advance

    Gianluca

    Tuesday, October 11, 2016 12:37 PM
  • User2148 posted

    Gianluca can you post a sample repo on github?

    Tuesday, October 11, 2016 1:02 PM
  • User65040 posted

    How about making a dependency object checklist? I'll start with my number one cause for "does not update":

    1. Check, if you haven't forgotten to derive your data model from INotifyPropertyChanged:

      class MyItem : INotifyPropertyChanged { ... }

    Tuesday, October 11, 2016 1:21 PM
  • User264645 posted

    Hi ThomasMielke, you're right. I forget INotifyPropertyChanged implementation...

    I'll try to add it and post the result..

    Thanks everyone!

    Gianluca

    Tuesday, October 11, 2016 1:34 PM
  • User264645 posted

    Great! It works! It was INotifyPropertyChanged... now I add implementation and that's ok!

    Thanks a lot

    Gianluca

    Tuesday, October 11, 2016 1:46 PM
  • User2148 posted

    Gianluca you can use Fody for PropertyChanged...

    Tuesday, October 11, 2016 1:48 PM
  • User264645 posted

    Sorry AlessandroCaliaro..I don't know it

    Tuesday, October 11, 2016 2:02 PM
  • Tuesday, October 11, 2016 2:17 PM
  • User264645 posted

    I'll take a look! Thanks

    Tuesday, October 11, 2016 2:19 PM
  • User278172 posted

    For me this ended up being that the model I was using for the generic ObservableCollection<> was not inheriting from INotifyPropertyChanged, the list was in my ViewModel but not the generic class model. Typical MVVM mistake. Hope this helps someone.

    Thursday, December 1, 2016 2:34 AM
  • User272130 posted

    Dear Its not a BUG, you just have to implement the INotifyPropertyChanged interface in your model (or adapter you can say) class. And when the values changes it will update the ui. For example you have class named as Student who has name and image property, then the adapter class is as follows

    public class StudentModel : INotifyPropertyChanged { string profileImage = ""; public event PropertyChangedEventHandler PropertyChanged;

        public string ProfileName { get; set; }
    
        public string ProfileImage
        {
            get
            {
                return profileImage;
            }
    
            set
            {
                profileImage= value;
                OnPropertyChanged("ProfileImage");
            }
        }
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this,
                    new PropertyChangedEventArgs(propertyName));
            }
        }
    }
    

    when the ProfileImage property changes (here we set image name) the list view ui updated.

    You just need to call add OnPropertyChanged thats it.... I hope, I helped someone. Thank You --- HP

    Saturday, December 17, 2016 5:04 AM
  • User267719 posted

    @JashPatel Thanks to point out right direction. By using collectionchanged, i can update my listview and show right display on my GUI.

    Tuesday, January 3, 2017 7:57 PM
  • User214229 posted

    Hello All... Xamarin forms document clearly mentions to use "ObservableCollection" instead of list to update any newly added items. please go through the link pasted below.

    ex: ObservableCollection employeeList = new ObservableCollection(); listView.ItemsSource = employeeList;

    //Mr. Mono will be added to the ListView because it uses an ObservableCollection employeeList.Add(new Employee(){ DisplayName="Mr. Mono"});

    Ref: https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/data-and-databinding/

    Thursday, January 19, 2017 4:59 AM
  • User155123 posted

    This works fine.

    @mkvonarx said: Hi

    Can anyone tell me why this simple code is not working as expected? Does the ListView control not listen for changes in the bound property?

    • Expected: when I click the Add button, the GUI (ListView) updates through the binding and shows the new element in the ObservableCollection.
    • Observed: GUI does not update but always shows the initial three items of the ObservableCollection.
    • Btw: OnAddButtonClicked() does get called and ListViewItems does get updated (checked in the debugger). Calling OnPropertyChanged("ListViewItems") inside OnAddButtonClicked() did not help either.
    • And: if I update the code as follows, the ListView works: add a Label control, bind that label to a 2nd property, update that property inside OnAddButtonClicked(), call OnPropertyChanged() from inside the property setter. So obviously this call to OnPropertyChanged() somehow triggers the ListView to get updated as well...
    • I'm now using Xamarin.Forms version 1.1.0.6201. Didn't work with the previous version either.

    XAML:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Test1.MainPage"
                 Padding="10" Title="MainPageXaml">
        <StackLayout VerticalOptions="StartAndExpand" HorizontalOptions="Fill">
            <Button Text="Add" Clicked="OnAddButtonClicked" />
            <ListView ItemsSource="{Binding ListViewItems}" />
        </StackLayout>
    </ContentPage>
    

    C#:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            ListViewItems = new ObservableCollection<string> { "one", "two", "three" };
            BindingContext = this;
        }
    
        private void OnAddButtonClicked(object sender, EventArgs e)
        {
            ListViewItems.Add(DateTime.Now.ToString());
            // OnPropertyChanged("ListViewItems");
        }
    
        public ObservableCollection<string> ListViewItems { get; set; }
    }
    

    Markus

    Monday, January 30, 2017 4:11 PM
  • User155123 posted

    Works fine.

    Monday, January 30, 2017 4:11 PM
  • User288719 posted

    If you add { get; set; } in the property of the class that you are trying to render then it works.

    Thursday, February 9, 2017 4:36 PM
  • User296603 posted

    Issue *Solved* By Implementing *INotifyPropertyChanged *for Model Class like below

    ObservableCollection<MyModel> listviewItemSource=new ObservableCollection<MyModel>();

    public class *MyModel *: *INotifyPropertyChanged * { private string name ; public string Name { get { return name; } set { this.name = value; OnPropertyChanged("Name"); } } . . . . . public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName]string propertyName = null) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }

    }

    Tuesday, February 21, 2017 9:45 AM
  • User2148 posted

    I suggest you to take a look to PropertyChanged.Fody

    Tuesday, February 21, 2017 9:47 AM
  • User301912 posted

    A possible fix might be for you to reset the item source.

    https://forums.xamarin.com/discussion/18868/tableview-reloaddata-equivalent-for-listview

    I am using ReactiveLists but the fix worked for me so I guess it's another angle for you to try.

    Tuesday, March 14, 2017 10:36 AM
  • User220999 posted

    I could resolve the issue by setting the ListViewCachingStrategy of the ListView to ListViewCachingStrategy.RetainElement instead of ListViewCachingStrategy.RecycleElement.

    Wednesday, March 15, 2017 12:37 PM
  • User277526 posted

    I ended up with the same bug , List's ItemSource gets updated but does not reflect in UI on iOS, until I change the Orientation of the device. It worked perfectly fine on Andorid. Any workaround to make it work in iOS ? Thanks

    Saturday, March 25, 2017 10:33 AM
  • User85908 posted

    @RobCrabtree Thanks, as suggested, wrapping in a grid with a RowDefinition of "*" fixed the problem.

    Another weird bug - fixed in a weird way.

    Fix is from September 2014! It's 2017 now... :/

    Tuesday, April 11, 2017 12:33 AM
  • User113187 posted

    Three years pass away.... Same issue to me today.

    Monday, May 15, 2017 4:10 PM
  • User317949 posted

    hi i have listview accordion in a page and its expands but can't able to collapse when i again tap the list item. i have a stacklayout (accordion) which is inside the listview and its controlled by IsVisible control on stackLayout. my question is it get expand but cant able to collapse?

    Tuesday, May 16, 2017 9:59 AM
  • User307050 posted

    @M2M said: Hi @mkvonarx? , How did you resolve this problem? I get the same problem. After reloading the observationcollection datasource, nothing change but if I rotate the device the listview update and show the items correctly

    In this case, I have the follow solution:

    xaml

    code behind:

    A. listview.IsRefreshing = true; B. update your observableCollection. C. listview.IsRefreshing = false;

    I Hope it helps

    Wednesday, May 17, 2017 6:38 AM
  • User307050 posted

    stop thinking its a bug. It's not a bug. Is the way how you update your listview.

    listview.isRefreshing = true;

    //update your observableCollection. do not forget INotify etc..

    //even you could do some tricks like delay(1000) etc

    listview.isRefreshing = false;

    Wednesday, May 17, 2017 6:47 AM
  • User119228 posted

    I had this problem too and discovered that by switching the declaration of the ObservableCollection in the view model from a field to a property the problem went away.

    i.e. bad:

    public class MasterViewModel : INotifyPropertyChanged
    {
       public ObservableCollection<DetailViewModel> ListItemData = new ObservableCollection<DetailViewModel>();
    }
    

    vs. good:

    public class MasterViewModel : INotifyPropertyChanged
    {
       private ObservableCollection<DetailViewModel> _listItemData = new ObservableCollection<DetailViewModel>();
       public ObservableCollection<DetailViewModel> ListItemData 
       {
          get { return _listItemData; }
          set { _listItemData = value; }
       }
    }
    

    note: omitted INotifyPropertyChanged handling for brevity.

    For those of you who declare ListItemData in your controller class instead of a VM just change the declaration so it's a property instead of a field in your controller.

    Monday, June 19, 2017 6:07 AM
  • User65040 posted

    Good one!

    Comes on my Dependency Object Checklist:

    // 1. Check, if you haven't forgotten to derive your data model from INotifyPropertyChanged:
    
    class MyItem : INotifyPropertyChanged
    {
          private String _text;
          public String Text
          {
              get => _text;
              set => SetProperty(ref _text, value);
          }
    }
    
    // 2. Check, if you haven't forgotten to derive your ViewModel from INotifyPropertyChanged
    //    and declare your ObservableCollection itself as a dependency property:
    
    public class MyViewModel : INotifyPropertyChanged
    {
       private ObservableCollection<MyItem> _listItemData = new ObservableCollection<MyItem>();
       public ObservableCollection<MyItem> ListItemData 
       {
          get => _listItemData;
          set => SetProperty(ref _listItemData, value);
       }
    }
    

    note: omitted SetProperty and subsequent OnPropertyChanged implementaions for brevity -- see here for details: https://www.danrigby.com/2015/09/12/inotifypropertychanged-the-net-4-6-way (consequently, you should provide an abstract class -- in the link it's BindableBase -- instead of using INotifyPropertyChanged directly, so you won't need to implement SetProperty and OnPropertyChanged in each class.)

    Monday, June 19, 2017 1:01 PM
  • User199525 posted

    The real problem is not the ObservableCollection, INotifyPropertyChanged, Etc. The Real problem is the property ITEMSSOURCE's ListView, That not refresh the List, i do:

    DataContext.TextProperty = "Two"; //Change from One to Two the Text's Label DataContext.CollectionBooks = DataContext.CollectionBooks; //Not Refresh List DataContext.OnPropertyChanged("Collection_Books"); //Same, Not Refresh List

    But if we Bind the Collection_Books to a Text's Label and a converter the value change, example: Count

    I did:

    Listview_Books.RemoveBinding(ListView.ItemsSourceProperty);

    And:

    ListviewBooks.SetBinding(ListView.ItemsSourceProperty, new Binding("CollectionBooks", BindingMode.Default, null, null, null, DataContext));

    And don't do nothing. but if we do:

    ListviewBooks.Itemssource = DataContext.CollectionBooks;

    neither works, we need really to do:

    Listview_Books.Itemssource = null;

    ListviewBooks.Itemssource = DataContext.CollectionBooks;

    Sorry my shit english, i speak spanish and i did without translate ;).

    Friday, December 1, 2017 4:42 AM
  • User65040 posted

    This is really not the way it's meant to be. I've got another one for my Dependency Object Checklist -- maybe this will help you:

    // 3. Check, if you are on the user interface thread:
    
    public class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<MyItem> _listItemData = new ObservableCollection<MyItem>();
        public ObservableCollection<MyItem> ListItemData 
        {
           get => _listItemData;
           set => SetProperty(ref _listItemData, value);
        }
    
        public MyViewModel()
        {
            ListItemData.CollectionChanged += OnCollectionChanged;
        }
    
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            var handler = CollectionChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    
        public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
             if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
            {
                Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
                    RaiseCollectionChanged(e);
                });
            }
        }
    }
    
    or maybe just:
    
    Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
        (MyViewModel)vm.ListItemData.Add(new MyItem());
    }
    
    Monday, December 25, 2017 3:19 PM
  • User368417 posted

    Hi, had such issue and the solution was to add items to the observable collection one at a time, when you just create a new observable collection for the property you bound you will face that issue, just do as I say and everything will be fine.

    Monday, June 4, 2018 2:18 PM
  • User274200 posted

    This still has bugs. My model implements INotifyPropertyChanged and it does not refresh view. I also implemented list with public get and set and it does not refresh view. I tried it with private member also and it does not refresh view.

    This is not optimized but always works for me. Calling method in code-behind from view model and setting ItemSource over x:Name element. This works.

    Wednesday, September 26, 2018 8:47 PM
  • User380801 posted

    Hello everyone,

    Unfortunately I've got the same problem. The loading of my ObservableCollection isn't ready on time but it somehow doesn't notify the view when it's ready. I've tried all the solutions above but none of them seems to work. Can somebody help me out?

    This is the model Round, it inherits from a BaseModel : INotifyPropertyChanged.

    public class Round : BaseModel { public string Id { get; set; } public Answer _SelectedAnswer { get; set; }

        private ImageSource _RealPicture { get; set; }
        public ImageSource RealPicture
        {
            get { return _RealPicture; }
            set { _RealPicture = value; RaisePropertyChanged(nameof(RealPicture)); }
        }
    
        private List<Answer> _Answers { get; set; }
        public List<Answer> Answers
        {
            get { return _Answers; }
            set { _Answers = value; RaisePropertyChanged(nameof(RealPicture)); }
        }
    
        private Answer _RightAnswer { get; set; }
        public Answer RightAnswer
        {
            get { return _RightAnswer; }
            set { _RightAnswer = value; RaisePropertyChanged(nameof(RightAnswer)); }
        }
    

    This is the viewmodel GameDetailViewModel that inherits from BaseViewModel : INotifyPropertyChanged.

    public class GameDetailViewModel : BaseViewModel { public int hour = 0, min = 0, sec = 0, lap = 13; public Timer timer; public Game Game { get; set; } public Round Round { get; set; } public Command LoadRoundsCommand { get; set; } public Command StartPlayTime { get; set; }

        private ObservableCollection<Round> rounds = new ObservableCollection<Round>();
        public ObservableCollection<Round> Rounds
        { get { return rounds; }
          set { rounds = value; OnPropertyChanged(nameof(Rounds)); }
        }
    
        public GameDetailViewModel(Game game = null)
        {
            Title = game?.Text;
            Game = game;
            Rounds = new ObservableCollection<Round>();
            Rounds.CollectionChanged += OnCollectionChanged;
            LoadRoundsCommand = new Command(async () => await ExecuteLoadRoundsCommand());
            StartPlayTime = new Command(StartStopwatch);
    
        }
    
        public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
            {
                Device.BeginInvokeOnMainThread(() => {
                    RaiseCollectionChanged(e);
                });
            }
        }
    
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            CollectionChanged?.Invoke(this, e);
        }
    
        async Task ExecuteLoadRoundsCommand()
        {
            if (IsBusy)
                return;
    
            IsBusy = true;
    
            try
            {
                Rounds.Clear();
    
                var rounds = await RoundDataStore.GetItemsAsync(true); 
                foreach (var round in rounds)
                {
                    Rounds.Add(round);
                }
                Round = GetRound(); 
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }
            finally
            {
                IsBusy = false;
            }
    

    This is the contentpage, the C# part.

    public partial class Game1DetailPage : ContentPage
    {
        public GameDetailViewModel viewModel;
    
        public Game1DetailPage(GameDetailViewModel viewModel)
        {
            InitializeComponent();
    
            BindingContext = this.viewModel = viewModel;
            InitializeGame();
        }
    
        protected override void OnAppearing()
        {
            base.OnAppearing();
            viewModel.LoadRoundsCommand.Execute(null);
        }
    

    This is the contengpage with the XAML part.

            <Frame OutlineColor="#e91e63"
                   HasShadow="True"
                   HorizontalOptions="Center" 
                   Padding="0"
                   Margin="0">
                <Image Source="{Binding Round.RealPicture}"/>
            </Frame>
            <Picker x:Name="picker" 
                Title="Select an answer"
                ItemsSource="{Binding Round.Answers}"
                SelectedItem="{Binding SelectedAnswer}"
                SelectedIndexChanged="OnPickerSelectedIndexChanged" >
            </Picker>
            <Button x:Name="buttonSubmitAnswer"
                Margin="0,10,0,0" 
                HorizontalOptions="Center"
                VerticalOptions="End"
                BindingContext="{x:Reference picker}"
                Text="Submit answer:"
                Command="{Binding CheckAnswerCommand}"
                Clicked="OnButtonSubmitAnswerClicked"
                BackgroundColor="#e91e63" 
                TextColor="White" />
        </StackLayout>
    </ContentView>
    

    Can somebody tell me what I'm doing wrong?

    Wednesday, December 19, 2018 11:07 AM
  • User380801 posted

    In the end I solved it!

    I changed

    public Round Round { get; set; }

    to

    public Round round; public Round Round { get { return round; } set { round = value; OnPropertyChanged(nameof(Round)); } }

    The inheritance of BaseModel and the following code are apparently not necessary in my case:

    //Rounds.CollectionChanged += OnCollectionChanged;

        //public void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        //{
        //    if (e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove)
        //    {
        //        Device.BeginInvokeOnMainThread(() => {
        //            RaiseCollectionChanged(e);
        //        });
        //    }
        //}
    
        //public event NotifyCollectionChangedEventHandler CollectionChanged;
        //void RaiseCollectionChanged(NotifyCollectionChangedEventArgs e)
        //{
        //    CollectionChanged?.Invoke(this, e);
        //}
    
    Wednesday, December 19, 2018 12:30 PM
  • User168260 posted

    Hi everyboy. PLEAE HELP MMMMMMMMMMMMEEEEEE :'( I have a ListView inside of a CarouselView. I fired CarouselView_ItemSelected and Exceute a command for getting data for listView. But The ListView just update in UI and showing data for the first time (when carsoulView has been loaded), and when i swipe, updated data doesn't show in the ListView and it's empty (:

    Sunday, February 10, 2019 12:16 PM
  • User65040 posted
    1. Check, if you have forgotten to derive your data model from INotifyPropertyChanged.
    2. Check, if you have forgotten to derive your ViewModel from INotifyPropertyChanged and declare your ObservableCollection itself as a dependency property.
    3. Check, if you are on the user interface thread.
    Monday, February 11, 2019 11:00 AM
  • User168260 posted

    Dear ThomasMielke Thanks a lot for your response. I checked it according to your description and i think it was OK! I'm new in Xamarin.Form, But I saw a lot of training about that and created it according to them. Could you please check my attached code and tell me which part is wrong? ?? Thank you so much ????

    Monday, February 11, 2019 5:58 PM
  • User65040 posted

    This smells like case 3:

    Try to encapsulate the code where you renew and fill UserLessonWords in function GetUserLessonWordsAsync() like so:

            if (myTask.Result != null)
            {
                Xamarin.Forms.Device.BeginInvokeOnMainThread(() => {
                    UserLessonWords = new ObservableCollection<LessonWordModel>();
                    foreach (var lessonWord in myTask.Result)
                        UserLessonWords.Add(lessonWord);
                }
            }
    
    Monday, February 11, 2019 9:56 PM
  • User168260 posted

    Dear ThomasMielke Thank you so much for your response. ????????? I changed it according to your code. but it didn't work :(

    Tuesday, February 12, 2019 6:53 AM
  • User391365 posted

    okay, you guys i tried it all, but this fixed it for me: What i mean by this is after performin action on one of the listview items: 1. set the whatever source you had to NULL 2. set selected item to NULL 3. connect it back to the source!

    Hope it helps!

    Sunday, December 22, 2019 9:18 PM
  • User389176 posted

    The problem lies on not defining templates of the listview.

    Add view and bind here

    Wednesday, March 11, 2020 1:54 PM
  • User389176 posted

    The problem lies on not defining templates of the listview.

    Add view and bind here

    Wednesday, March 11, 2020 1:54 PM