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.
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
Hey Lance, was there a resolution to this problem? I am now facing the same issue?
Thanks,
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
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?
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
That seems to have done the trick.
Thanks for the assistance Lance
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();
}
}
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
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.
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
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?
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
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
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
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
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
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.
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"
?>
<
ContentPage
xmlns
=
"http://xamarin.com/schemas/2014/forms"
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.
Solution: Use 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
Read again my post, please!
I talk about WPF application (etc. Windows 7), not Xamarin app
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