Forum Xamarin Xamarin.Forms

What are consequences/implications of using an ObservableCollection in this fashion?

MREmeMREme Member ✭✭

This appears to allow me to do background work and when ready, supply the data to the collection and still get the UI to update with out a lot of fuss. Perhaps I am wrong as I am new at this. Having the option to set the flag means I can disable the "feature" when necessary (not even sure if that will be necessary but seemed easy enough to implement). Would this be a valid way to do background work and yet still update the UI?

```C#
//Override ObservableCollection with my own implementation
public class MYObservableCollection : ObservableCollection
{
public MYObservableCollection() : base()
{ }
public MYObservableCollection(IEnumerable collection) : base(collection)
{ }

​ public MYObservableCollection(List list) : base(list)
​ { }

​ ///


​ /// Boolean used to enforce adding, inserting, and removing of items on the main thread.
​ /// When set the three methods will only execute on the Main UI Thread, which ensures the UI
​ /// is updated when the CollectionChanged event occurs.
​ ///

​ public virtual bool EnforceMainThreadExecution
​ {
​ get;set;
​ }

​ ///


​ /// Inserts the item into the collection but checks to see if the thread is the Main UI thread or not.
​ /// If it is NOT the call to insert the item (base.InsertItem) is called on the Main UI thread.
​ /// If the EnforceMainThreadExecution flag is NOT set the call is made on the current running thread.
​ ///

​ ///


​ ///
​ protected override void InsertItem(int index, T item)
​ {
​ if (EnforceMainThreadExecution)
​ {
​ //Using
​ if (!MainThread.IsMainThread)
​ {
​ MainThread.BeginInvokeOnMainThread(() =>
​ {
​ base.InsertItem(index, item);
​ });
​ }
​ else
​ {
​ base.InsertItem(index, item);
​ }
​ }
​ else
​ {
​ base.InsertItem(index, item);
​ }
​ }

//These methods in the same way but removed for simplicity
protected override void SetItem(int index, T item){}

//These methods in the same way but removed for simplicity
protected override void RemoveItem(int index){}
}

//USAGE Example, (obviously it would have many other uses. In a view model of some page in my app):
public void HeaderTapped(object sender)
{
//Determine which button was pressed
int selectedIndex = -1;

​ ImageButton senderIButton = sender as ImageButton;

​ selectedIndex = expandedGroupsLocal.IndexOf(((MainMenuGroup)(senderIButton).CommandParameter));

​ if (selectedIndex > -1)
​ {
​ allGroupsLocal[selectedIndex].Expanded = !allGroupsLocal[selectedIndex].Expanded;
​ }

​ //update the menu in the background
​ System.Threading.Tasks.Task.Run(() => UpdateListContent());
​ }

​ private async System.Threading.Tasks.Task UpdateListContent()
​ {
​ bool retVal = false;

​ await System.Threading.Tasks.Task.Run(() =>
​ {
​ expandedGroupsLocal = new MYObservableCollection();
​ expandedGroupsLocal.EnforceMainThreadExecution = true;//Note the flag gets set here before I add items to the collection

​ foreach (MainMenuGroup group in allGroupsLocal)
​ {
​ MainMenuGroup newGroup = new MainMenuGroup(group.Title, group.ShortName, group.Expanded);
​ newGroup.MenuCount = group.Count;
​ if (group.Expanded)
​ {
​ foreach (MainPageMenuItem mnu in group)
​ {
​ //Add expanded group to menu
​ newGroup.Add(mnu);
​ }
​ }
​ expandedGroupsLocal.Add(newGroup);
​ }
​ });
​ return retVal;
​ }
```

Answers

  • JarvanJarvan Member, Xamarin Team Xamurai

    to do background work and yet still update the UI?

    To update the UI, the Model class and the ViewModel class should inherit from INotifyPropertyChanged interface. Implementing this interface in a view model or model class allows the class to provide change notifications to any data-bound controls in the view when the underlying property value changes.

    Try add the function code in Model class or the ViewModel class instead of custom ObservableCollection.

Sign In or Register to comment.