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;
}
```