Skip to content

Instantly share code, notes, and snippets.

@jsauve
Last active January 17, 2020 22:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsauve/9fa5460c42961e55edb3e9c5c018868b to your computer and use it in GitHub Desktop.
Save jsauve/9fa5460c42961e55edb3e9c5c018868b to your computer and use it in GitHub Desktop.
using System;
using MvvmHelpers;
using PropertyChanged;
using Xamarin.Forms;
namespace Blah
{
// The rest of this page is of course defined in XAML
public partial class MyPage : ContentPage
{
protected MyViewModel ViewModel => BindingContext as MyViewModel;
public MyPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
if (!ViewModel.IsLoaded) // If you want to automatically reload data every time the view appears, remove IsLoaded check
ViewModel.LoadDataCommand.ExecuteAsync().SafeFireAndForget(); // use SafeFireAndForget(). DON'T mark OnAppearing() as async. "async void" is evil: https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming
}
}
// When PropertyChanged.Fody is all setup properly, this attribute will make all your public properties fire PropertyChanged events when their values change.
// This viewmodel should of course live in its own file. It's just here for the convenience of the example.
[AddINotifyPropertyChangedInterface]
public class MyViewModel
{
public bool IsLoaded { get; }
// Your ListView's or CollectionView's "IsRefreshing" property should be bound to this
public bool IsRefreshing { get; }
// you ListView's or CollectionView's ItemSource property should be bound to this collection
public ObservableRangeCollection<MyThing> MyThings { get; } = new ObservableRangeCollection<MyThing>();
// This will be called in OnAppearing(), but you can also bind it to your RefreshCommand property in your ListView or Collection. Then you can easiliy refresh data with pull-to-refresh.
public AsyncCommand LoadDataCommand { get; } = new AsyncCommand(async () => ExecuteLoadDataCommand());
public MyViewModel()
{
}
async task ExecuteLoadDataCommand()
{
try
{
if (IsRefreshing)
true;
IsRefreshing = true;
MyThings.Clear();
var myThings = await // Fetch some things asynchously from whatever service or client or DB you want. But do it ASYNCHRONOUSLY!
MyThings.AddRange(myThings);
}
catch (Exception ex)
{
// log it or present a message to the user or whatever
}
finally
{
IsRefreshing = false;
IsLoaded = true;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment