-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Create a collection of type AsyncObservableCollection<T>
somewhere in your code (your view model, for example).
public class MainViewModel
{
public AsyncObservableCollection<string> Items { get; set; } = new AsyncObservableCollection<string>();
}
Before using it, you need to initialize the collection from each platform specific project. In my example, I have a WPF .NET Framework project and a Xamarin.Forms .NET Standard project. I'll initialize the collections for my view model from each platform, before I start using the view model.
The collection implements the IAsyncObservableCollection
interface, so you can find all of them with reflection (see the InitAsyncCollectionsAutomatically
method) or initialize them manually (see the InitAsyncCollections
method).
I have this method in the view (WPF Window) that is associated with the view model. It get's called from the constructor of the view.
public MainWindow()
{
InitializeComponent();
_model = new MainViewModel();
this.DataContext = _model;
//call the initialize method for async collections
InitAsyncCollectionsAutomatically(_model);
}
/// <summary>
/// Initializes all properties that implement the IAsyncObservableCollection interface
/// </summary>
/// <param name="model">The object, that holds the collections</param>
private void InitAsyncCollectionsAutomatically(object model)
{
//select all properties that implement IAsyncObservableCollection
var collections = model.GetType().GetProperties()
.Where(a => typeof(IAsyncObservableCollection).IsAssignableFrom(a.PropertyType))
.Select(a => a.GetValue(model) as IAsyncObservableCollection);
//initialize them all
InitAsyncCollections(collections);
}
/// <summary>
/// Initializes an enumerable of IAsyncObservableCollection
/// </summary>
/// <param name="collections">The collections that need to be initialized</param>
private void InitAsyncCollections(IEnumerable<IAsyncObservableCollection> collections)
{
foreach (var collection in collections)
{
//initialize the collection
collection.Init(action => Dispatcher?.Invoke(() => action?.Invoke()));
}
}
And the exact same methods (with a Xamarin.Forms dispatcher) is in my view (Xamarin.Forms ContentPage), and it get's called from the constructor of the view, as well.
public MainPage()
{
InitializeComponent();
_model = new MainViewModel();
this.BindingContext = _model;
//call the initialize method for async collections
InitAsyncCollectionsAutomatically(_model);
}
/// <summary>
/// Initializes all properties that implement the IAsyncObservableCollection interface
/// </summary>
/// <param name="model">The object, that holds the collections</param>
private void InitAsyncCollectionsAutomatically(object model)
{
//select all properties that implement IAsyncObservableCollection
var collections = model.GetType().GetProperties()
.Where(a => typeof(IAsyncObservableCollection).IsAssignableFrom(a.PropertyType))
.Select(a => a.GetValue(model) as IAsyncObservableCollection);
//initialize them all
InitAsyncCollections(collections);
}
/// <summary>
/// Initializes an enumerable of IAsyncObservableCollection
/// </summary>
/// <param name="collections">The collections that need to be initialized</param>
private void InitAsyncCollections(IEnumerable<IAsyncObservableCollection> collections)
{
foreach (var collection in collections)
{
//initialize the collection
collection.Init(action => Device.BeginInvokeOnMainThread(() => action?.Invoke()));
}
}
Now you can do things like this, freely.
await Task.Run(() =>
{
Items.Clear();
Items.Add("Item 1");
Items.AddRange(new []
{
"Item 2",
"Item 3",
});
});