ListView binding to ObservableCollection does not update GUI

2 Answers 6746 Views
ListView
Mario
Top achievements
Rank 1
Mario asked on 05 Apr 2017, 03:00 PM
Hello, I have a RadListView bound to an ObservableCollection inside RadSideDrawer.DrawerContent and my ListView doesn't show the items until the device changes orientation. I'm actually using the Recipes source code provided in the Telerik UI for Xamarin Andriod App but I can't get the list to show the items. The only code that I don't have to fully run the sample would be the code in the OnAppearing override in Example.xaml.cs. Any help would be much appreciated.
Lance | Manager Technical Support
Telerik team
commented on 07 Apr 2017, 05:37 PM

Hello Mario,

I have replied to this question in the Support Ticket you opened with the same question. To make sure there is no miscommunication while we work to resolve this issue, I'll keep the communication in the Support Ticket.

If you want to, you can come back to this forum post and update the community with the results once the case has been resolved.

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Ben
Top achievements
Rank 1
commented on 29 May 2017, 05:16 AM

Hey Lance, was there a resolution to this problem? I am now facing the same issue?

 

Thanks,

Ben.

Stefan Nenchev
Telerik team
commented on 30 May 2017, 08:43 AM

Hello Ben,

We were not able to replicate the behavior that Marko has reported so no further investigation has been conducted. Can you please share more information on your scenario? Do you test the behavior our samples? I have attached a sample project for your reference which is based on the "Recipes" project. It would be great if you can modify the sample so that the undesired behavior is observed. Eventually, we can have a more detailed look and provide more concrete information.

Have a great rest of the week.

Regards,
Stefan Nenchev
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Ben
Top achievements
Rank 1
commented on 30 May 2017, 10:46 PM

Hey Stephan, I am no longer having the issue either, I think it was to do with custom observable collection I was using.
John
Top achievements
Rank 1
commented on 19 Jun 2017, 09:52 AM

I am having a similar issue however my scenario differs from your test scenario as I have a asynchronous call to an external api to load data. 

There fore I am forced to call this method from the on appearing method and not the constructor like in your example.

My theory is that the UI is already generated before the data is loaded and therefore my list view appears empty. 

When my task returns with the collection i add them to the observable collection but this does not update the UI for some reason.

Is there a refresh method we could use?

Lance | Manager Technical Support
Telerik team
commented on 19 Jun 2017, 03:11 PM

Hi John,

The primary purpose of ObservableCollection is that when items are added and removed, it fires off a CollectionChanged event and anything bound to it will be notified of changes.

A common mistake that occurs in this scenario is that the items are not being added to the same OC that is bound to the RadListView because it was replaced without PropChanged.

What you can do to ensure you're not accidentally replacing the collection is make it read-only, and add the items from your async work. Here's an example:

public class ViewModel
{
    private ObservableCollection<MyModel> dataItems;
    public ObservableCollection<MyModel> DataItems => dataItems ?? (dataItems = new ObservableCollection<MyModel>());
 
    public async void LoadItems()
    {
        // 1- get the items from the async call
        var apiCallResult = await DoWorkAsync();
 
        // 2 - add them to the bound collection
        foreach (var item in apiCallResult)
        {
            DataItems.Add(item);
        }
    }
}


If you're still not seeing the UI update, then the problem lies somewhere else and we'll need to see your code in order to debug it. Please reply back with your View and ViewModel so that I can replicate it.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
John
Top achievements
Rank 1
commented on 20 Jun 2017, 11:28 AM

That seems to have done the trick.

 

Thanks for the assistance Lance

lyndon
Top achievements
Rank 1
commented on 04 Sep 2017, 06:02 PM

I'm also seeing this issue with the radlist but not seeing the issue with a regular listview accessing the same collection.  I'm using an observablecollection that has elements added to it when on the screen load (i'm not creating the collection at that time, as I understand that creating the object will mess up the onchanged event from firing).  I'm using v2017.2.626.3.  
Lance | Manager Technical Support
Telerik team
commented on 05 Sep 2017, 02:52 PM

Hi Lyndon,

Since you didn't share your code, I'll need to make an assumption based on your described scenario. A common mistake that happens is:  instead of using Add/Remove on the ObservableCollection (O.C.), you replace the entire collection when your O.C. doesn't have PropertyChanged wired up.

For example, looking at the code I provided in my last reply, if you did the following you would no longer see items added:


public class ViewModel
{
    private ObservableCollection<MyModel> dataItems;
    public ObservableCollection<MyModel> DataItems => dataItems ?? (dataItems = new ObservableCollection<MyModel>());
  
    public async void LoadItems()
    {
        // This will replace the ObservableCollection entirely, instead of just adding items
        DataItems = await DoWorkAsync();

          // Any items added to DataItems will NOT be observable because you have replaced the instance of ObservableCollection
    }
}

In order to fix this, you need to either:

1 - Only add items from the work result (like you see in the example I sent John)
2 - Make sure your O.C. also has PropertyChanged wired up

Here's an example of #2:

private ObservableCollection<MyModel> dataItems;
 
public ObservableCollection<MyModel> DataItems
{
    get { return  dataItems ?? (dataItems = new ObservableCollection<MyModel>()); }
    set { dataItems = value; OnPropertyChanged(); }
}

Now, if you replaced the instance of the ObservableCollection, anything bound to it will be notified and items added/removed will appear in the RadListView.


If you're still having trouble, please open a support ticket here and attach the relevant code form your application so we can investigate further.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
lyndon
Top achievements
Rank 1
commented on 06 Sep 2017, 04:33 PM

Hello Lance.  I am confident I didn't reinitialize the collection as I understand that it will lose its binding with the XAML.  This is the case with all MVVM and not just your controls.  My code works fine with Xamarins Listview but not your Radlist.  Its odd because I'm using your Listview control in other parts of the application without this problem.

I created an unlisted youtube video illustrating the scenario.  https://www.youtube.com/watch?v=VTYyTvO86Ho

My VM code is as follows:

01.Class declaration, etc...
02.//THIS IS THE COLLECTION CALLED
03.public ObservableRangeCollection<FileReferenceHolder> FileList { get; set; }
04.         
05.        public PrismContentPage1ViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
06.        {
07.            _navigationService = navigationService;
08.            _eventAggregator = eventAggregator;
09.             
10.            //INIT OF COLLECTION
11.            FileList = new ObservableRangeCollection<FileReferenceHolder>();
12.            ItemSelectedCommand = new Command<FileReferenceHolder>(OpenFile);
13.            DeleteCommand = new Command<string>(async(string s)=>{await DeleteFile(s);});
14.        }
15. 
16.        public override async void OnNavigatingTo(NavigationParameters parameters)
17.        {
18.            base.OnNavigatingTo(parameters);
19.             
20.            //ON NAVIGATION.  NEVER RECREATING THE COLLECTION AS IT WILL BREAK BINDING.  WORKS FINE WITH XF LISTVIEW
21.            FileList.ReplaceRange(await new DocumentHelper().ListFolderContents());
22.        }

 

A couple of things to note:

1.  I'm using an observableRangeCollection. I've tried it with an ObservableCollection also, just to debug the situation

2. The keyboard click you hear before the screen on simulator clicks is the me simply saving the xaml file without making any changes.  This save, forced the simulator screen refresh.  I'm using a tool called LiveXaml that helps with displaying Xaml output. Of course, I've removed the LiveXaml nuget and tried things.  It is not having an effect on the display issue.  I've also tried running this page on a physical device.  I'm still experiencing the issue.

Please let me know if there is anything you need from me.

My environment:

Telerik UI Xamarin v2017.2.626.3
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.
Microsoft Visual Studio Enterprise 2017 
Version 15.3.3
VisualStudio.15.Release/15.3.3+26730.12
Microsoft .NET Framework
Version 4.7.02053
Xamarin   4.6.0.299 (b63523e27)
Xamarin.Android SDK   7.4.0.21 (2851083)
Xamarin.Android Reference Assemblies and MSBuild support.
Xamarin.iOS and Xamarin.Mac SDK   10.12.0.20 (80b8487)
Xamarin.iOS and Xamarin.Mac Reference Assemblies and MSBuild support.

Lance | Manager Technical Support
Telerik team
commented on 06 Sep 2017, 07:03 PM

Hi Lyndon,

Thank you for explaining your implementation further. To test if this is a timing issue, let use the base class's Add method and not the specialized ReplaceRange or AddRange methods.

For example, update your OnNavTo code to insert the items one at a time so we get notifications for each item.

public override async void OnNavigatingTo(NavigationParameters parameters)
{
    base.OnNavigatingTo(parameters);
 
    var folderContents = await new DocumentHelper().ListFolderContents();
 
    foreach (var folderItem in folderContents )
   {
         Debug.WriteLine("Folder item being added to FileList");
      FileList.Add(folderItem);
   }
}


Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
lyndon
Top achievements
Rank 1
commented on 06 Sep 2017, 08:03 PM

I changed the code as you suggested, but still no luck.  I'm now doing a simple for loop to add the items to the collection.  The output of "[0:] Folder item being added to FileList" is displaying in the output and the xamarin listview is displaying data, but the Radlist is not displaying data.

I will update my the version of Telerik.UI to 2017.2.818.1 to see if it helps.

Also, I'm logged in as a regular user, but I should be logged in under my Enterprise login where I have an Ultimate license with Ultimate support.  Should I create a ticket and reference this item or should I keep responding here?

 

Lance | Manager Technical Support
Telerik team
commented on 07 Sep 2017, 05:29 PM

Hi Lyndon,

Yes, please open a ticket so that we can investigate this further. The ticket will allow you to attached a reproducible application. I'll also be able to escalate the ticket to the RadListView development team, if necessary.

Go here to create a new ticket.

About your license, the account you're using to respond to this thread is your gmail email address, it only has an expired trial license for UI for Xamarin.  You'll need to log out and log back in with the account you have a license for UI for Xamarin in order to submit a ticket.

In the ticket please provide us with the following items:

- The complete XAML of the view containing the RadListView (including code-behind)
- Any supporting code I'll need (e.g. the model of the item, DocumentHelper class, etc)

Once you've created the ticket, reply back here with the ticket ID number and I'll assign myself and investigate further. If you're not able to open a ticket, please reply back here with those items, pasted in code blocks.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Lance | Manager Technical Support
Telerik team
commented on 07 Sep 2017, 09:32 PM

Hello Lyndon,

I have built out a sample application using full MVVM, find it attached. I used ReplaceRange on the RadListView's items source and it works as expected (go to StartPageViewModel at line 67).

Here's a screenshot at runtime (pressing button calls Refresh which increments the numbers after the emails):




As a rule, using ReplaceRange on an empty collection will not insert any items unless it finds a matching range. If your collection is empty, try using AddRange instead.

Can you update my attached demo so that it replicates the problem and we'll investigate further (note, you many need to add in your navigation system or PageBaseViewModel) framework. If your demo can repro the issue and I cannot find a fix, I'll escalate it to the UI for Xamairn development team.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
lyndon
Top achievements
Rank 1
commented on 08 Sep 2017, 06:04 PM

Thanks Lance.  I've created a new project and I'm working on recreating the issue in this new project.  I will open a ticket if the issue remains and I will update this thread either way.       
sandeep
Top achievements
Rank 1
commented on 15 Dec 2017, 01:51 PM

I am facing the same issue.

I have a telerik listview and i bind it to a ViewModel's Observable collection.

When I get data from a rest api, it should reflect on the control. But it doesn't.

It does get reflected on the native xamarin listview.

Sandeep

Lance | Manager Technical Support
Telerik team
commented on 15 Dec 2017, 09:41 PM

Hi Sandeep,

There are currently no known issues with binding to ObservableCollection. You can use this external API and RadListView demo to verify that it works as expected.

In your scenario, I cant tell what's specifically wrong and will need to see your code to diagnose further. Please open a support ticket here and attach your view/viewmodel so that I can debug it directly.

I only have one suggestion since you've confirmed that the vanilla ListView works with the collection:

Make sure you're not putting the RadListView inside a container that doesn't provide enough room for the RadListView (i.e. do not put it inside a StackLayout). I recommend using a Grid and place the RadListView in a RowDefinition with a height of star.

For example:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
 
    <AnotherControl Grid.Row="0" />
 
    <dataControls:RadListView ItemsSource="{Binding MyItems}" Grid.Row="1">
        ...
    </dataControls:RadListView>
</Grid>


Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
sandeep
Top achievements
Rank 1
commented on 18 Dec 2017, 01:15 PM

Hi Lance.

Thanks a lot! Adding the control in the Grid worked.

Maybe you would want to document it in the FAQ or the Listview sections?

 

Thanks,
Sandeep

Zlatko
Top achievements
Rank 1
commented on 25 Jun 2018, 08:37 AM

Hi Lance

The is still exist. 

We just need to use ListView instead RadListView. 

The same problem you, Telerik, have with RadComboBox. The WPF control ComboBox is works fine. 

Lance | Manager Technical Support
Telerik team
commented on 26 Jun 2018, 03:02 PM

Hello Zlatko,

We are not aware of any issues with binding the Xamarin RadListView to an ObservableCollection. Please open a Support Ticket here and share your code so that I can investigate further, (you can use the attached demo and update the code so that it replicates the problem).


Demo

Here's a full demo that illustrates RadListView respects the ObservableCollection CollectionChanged event:

Runtime Result



XAML

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ObservableCollectionTest.Portable"
             xmlns:telerikDataControls="clr-namespace:Telerik.XamarinForms.DataControls;assembly=Telerik.XamarinForms.DataControls"
             xmlns:listView="clr-namespace:Telerik.XamarinForms.DataControls.ListView;assembly=Telerik.XamarinForms.DataControls"
             x:Class="ObservableCollectionTest.Portable.MainPage">
     
    <ContentPage.BindingContext>
        <local:ViewModel />
    </ContentPage.BindingContext>
 
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
 
        <telerikDataControls:RadListView x:Name="listView" ItemsSource="{Binding Books}">
            <telerikDataControls:RadListView.ItemTemplate>
                <DataTemplate>
                    <listView:ListViewTextCell Text="{Binding Title}"
                                               Detail="{Binding Author}"
                                               TextColor="Black"
                                               DetailColor="Gray" />
                </DataTemplate>
            </telerikDataControls:RadListView.ItemTemplate>
            <telerikDataControls:RadListView.LayoutDefinition>
                <listView:ListViewLinearLayout ItemLength="70" />
            </telerikDataControls:RadListView.LayoutDefinition>
        </telerikDataControls:RadListView>
 
        <Button Text="Click Me"
                Command="{Binding AddBookCommand}"
                Grid.Row="1" />
    </Grid>
</ContentPage>

Code-Behind, Model and ViewModel

using System.Collections.ObjectModel;
using Xamarin.Forms;
 
namespace ObservableCollectionTest.Portable
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
 
    public class Book
    {
        public string Title { get; set; }
        public string Author { get; set; }
    }
 
    public class ViewModel
    {
        public ViewModel()
        {
            Books = new ObservableCollection<Book>{
                new Book{ Title = "The Fault in Our Stars ",  Author = "John Green"},
                new Book{ Title = "Divergent",  Author = "Veronica Roth"},
                new Book{ Title = "Gone Girl",  Author = "Gillian Flynn"},
                new Book{ Title = "Clockwork Angel",  Author = "Cassandra Clare"},
                new Book{ Title = "The Martian",  Author = "Andy Weir"},
                new Book{ Title = "Ready Player One",  Author = "Ernest Cline"},
                new Book{ Title = "The Lost Hero",  Author = "Rick Riordan"},
                new Book{ Title = "All the Light We Cannot See",  Author = "Anthony Doerr"},
                new Book{ Title = "Cinder",  Author = "Marissa Meyer"},
                new Book{ Title = "Me Before You",  Author = "Jojo Moyes"},
                new Book{ Title = "The Night Circus",  Author = "Erin Morgenstern"},
            };
 
            AddBookCommand = new Command(ExecuteAddBookCommand);
        }
 
        private void ExecuteAddBookCommand(object obj)
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                Books.Add(new Book
                {
                    Title = $"Book {Books.Count + 1}",
                    Author = "FooBar Author"
                });
            });
        }
 
        public ObservableCollection<Book> Books { get; set; }
 
        public Command AddBookCommand { get; set; }
    }
}

Run the attached demo and click the button to add items to the collection. You'll see the RadListView also gets updated


General Troubleshooting

A few reasons why you wouldn't see the RadListView items get updated:

Consideration: On iOS you need to make sure that the linker doesn't remove the control during compilation. 
SolutionUse XamlC (recommended) or give the control an x:Name

Consideration: On Android you need to make sure you give the control vertical space to expand into (this is the most likely reason in your case)
Solution: Making sure the RadListView is not under any StackLayout or Grid RowDefinition where Height=Auto. See this troubleshooting section.

Consideration: Adding items must be done on the UI thread
Solution: Make sure the logic that adds the item is being executed on the UI thread (use Device.BeginInvoke).

Consideration: Not all the dependencies have been added
Solution: Make sure you have added the RadListView Required Telerik References (to all the projects) and the Required Xamarin.Android Support Libraries


There are other things that might be wrong as well, but I can only determine what's wrong in your application by seeing your code directly.  I will see your support ticket come in and will start working on it.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Zlatko
Top achievements
Rank 1
commented on 25 Jul 2018, 09:37 AM

Read again my post, please!

I talk about WPF application (etc. Windows 7), not Xamarin app

Lance | Manager Technical Support
Telerik team
commented on 25 Jul 2018, 11:59 AM

Hi Zlatko,

This forum is for UI for Xamarin, which is why I answered in the context of Xamarin RadListView. Additionally, Telerik UI for WPF doesn't have a RadListView.

I can't move this thread to the UI for WPF category because there are initial posts pertaining to UI for Xamarin, can you please re-post your question in the WPF forums for RadListBox so that the UI for WPF engineers can assist further.

Here are the links to assist:

https://www.telerik.com/forums/wpf/listbox
https://www.telerik.com/forums/wpf/combobox

Please also provide the code you're using so that they can determine what the problem is withing that specific code.

I apologize for the inconvenience, thank you for your understanding.

Regards,
Lance | Tech Support Engineer, Sr.
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items

2 Answers, 1 is accepted

Sort by
0
Craig
Top achievements
Rank 1
answered on 27 Sep 2017, 03:24 AM

Hi all

I copy / pasted the xaml code from Telerik's Getting Started page for the ListView.  I then spent the best part of a day trying to get it to update when the ObservableCollection changed.  I had to remove the telerikDataControls:RadListView.BindingContext section (possibly because I'm using FreshMvvm) as well as set the VerticalOption to FillAndExpand.

Cheers
Craig

Andy
Top achievements
Rank 1
Veteran
commented on 28 Oct 2017, 09:05 PM

Just chiming in here in agreement- I couldn't get it to work, then I changed verticaloptions to fillandexpand and it's working- give that a shot.
0
Zlatko
Top achievements
Rank 1
answered on 25 Jun 2018, 08:07 AM

The problem is in RadComboBox.

Just remove "Rad" and all will be OK. :)

Telerik, please be careful !

 

Tags
ListView
Asked by
Mario
Top achievements
Rank 1
Answers by
Craig
Top achievements
Rank 1
Zlatko
Top achievements
Rank 1
Share this question
or