We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Adding items at runtime in MVVM setup using events (eg timer elapsed or other event)

Good day,

I have a service that is providing data through an event to a sflistview in a Prism, Xamarin Forms example.
I have recreated the symptoms using a timer event that adds items to a Observable collection that is binded to the listviews itemsouce.
Examples I have seen use code behind and is therefore not applicable to my requirement.
Kindly have a look a the page2 xaml and viewmodel files.
In principle I am trying add items when the timer elapsed event is fired.
Adding an item to the Observable collection in the OnTimedEvent handler seems to break any further dealings with the collection and listview.
I have also added a button that when clicked (using command binded to DelegateCommand) adds items to the listview collection - this works as expected.

Request:
Kindly advise what I am doing wrong in this approach and provide some suggestions on how to fix it.
(Why is command delegate working but not timer event handler)

Warm regards

Ian

Attachment: Sample1_bd099a91.zip

3 Replies

DB Dinesh Babu Yadav Syncfusion Team May 15, 2019 10:05 AM UTC

Hi Ian, 
 
Thanks for using Syncfusion products. 
 
We have checked the reported query in the given sample. We would like to inform you that timer didn’t start in Page2ViewModel after initialization which causes the reported issue. We have attached the modified sample along with code snippet for your reference, please find the sample from below. 
 
 
 
public class Page2ViewModel : ViewModelBase 
{ 
            public Page2ViewModel(INavigationService navigationService) 
            : base(navigationService) 
        {  
            AddItem = new DelegateCommand<string>(OnAddItem); 
            GotoPage1 = new DelegateCommand<string>(OnGotoPage2); 
             
            for ( int a = 0; a < 5; a++) 
            { 
                Items _Item = new Items(); 
                _Number++; 
                _Item.Number = _Number.ToString(); 
                _Item.Name = "Constructor name"; 
                ItemBucket.Add(_Item); 
            } 
 
            timer = new System.Timers.Timer(); 
            timer.Interval = 1000; 
            timer.Start(); 
            timer.Elapsed += OnTimedEvent; 
            timer.AutoReset = true; 
            timer.Enabled = true; 
 
        } 
           
        private void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e) 
        { 
            Items _Item = new Items(); 
 
            Device.BeginInvokeOnMainThread(async () => 
            { 
                await Task.Delay(200); 
                _Number++; 
                _Item.Number = _Number.ToString(); 
                _Item.Name = "Timer name"; 
                ItemBucket.Add(_Item); 
            }); 
        } 
} 
 
Please let us know whether sample meets your requirement. 
 
Regards, 
Dinesh Babu Yadav 
 



IA Ian May 15, 2019 01:40 PM UTC

Hello Dinesh,

Thank you for the response.
The solution you provided :

Device.BeginInvokeOnMainThread(async () =>
            {
                await Task.Delay(200);
                _Number++;
                _Item.Number = _Number.ToString();
                _Item.Name = "Timer name";
                ItemBucket.Add(_Item);
            });

works as required.

The issue is not so much with timer.Start() ( it works even if commented out!) but rather Invoking the update of the list in the main UI thread.

Once again, thank you for the quick response.

Warm regards

Ian


DB Dinesh Babu Yadav Syncfusion Team May 16, 2019 04:38 AM UTC

Hi Lan, 
 
Thanks for the update. Please let us know if you require further assistance. 
 
Regards, 
Dinesh Babu Yadav 
 


Loader.
Live Chat Icon For mobile
Up arrow icon