I can not lie when I say I LOVE pull to refresh in apps. Just search my blog and you will see tons of posts on how to implement it in Android, iOS, MVVMCross, and of course my crazy custom implementations for Xamarin.Forms. While those were nice custom renderers that provided a simple API, we finally have something official from Jason and the Xamarin.Forms team in 1.4.0, which released this week. The API looks strikingly familiar:
I couldn’t explain how it works better than the official release notes:
When the user triggers a PullToRefresh the Command will be invoked and the Refreshed event emitted. IsRefreshing will be set to true. The ICommand.CanExecute property is respected. The user must either call EndRefresh or assign IsRefreshing to false in order to end the refresh state.
So, how would you implement this in your ViewModel? Well I start all things off with a bool called IsBusy that tracks if we are loading data on the page:
We can use this to bind to our IsRefreshing and use it as a CanExecute flag for our ICommand. Next is to setup some sort of ICommand and method that will be refreshing our data. In this example I am updating my Hanselman.Forms app’s tweets page to have pull to refresh, so here is the code that refreshes tweets:
Notice I am using my IsBusy as a control for CanExecute, and also after I change it I call the Command’s ChangeCanExecute method to ensure anyone listening knows to update their status. You can make this a bit more clever if you desire in the properties getter/setter.
Finally is the DataBinding part and you will need to setup and bind up 3 properties: IsPullToRefreshEnabled, RefreshCommand, and IsRefreshing.
Notice I am only Binding OneWay on IsRefreshing. This means that my ViewModel can notify and change the IsRefreshing, but the Refresh view is not in control of my IsBusy. This is only important because I always check IsBusy ahead of time when I run my refresh logic. I am also using IsBusy to modify the CanExecute so I don’t want any outside forces modifying it.
And there you have it, let’s see it in action: