Publié
vendredi 4 mai 2012 13:13
par
Groc
Sur Windows Phone, lorsque j’ai des appels à des services qui s’enchainent, j’aime assez voir le status des opérations s’afficher dans le progress indicator pour bien montrer à l’utilisateur qu’il se passe des choses. Et pour que cela soit encore plus joli, j’aimerais que le dernier message, le plus important (ie. “upload terminé avec succès”), reste affiché quelques secondes. C’est le genre de chose que rx permet de faire très simplement, simplifiant également la concurrence.
Voici ma page d’exemple : un toggleswitch permet de déterminer si le prochain message sera un message de fin d’opérations, càd qu’il doit rester affihé quelques secondes puis disparaitre, un bouton pour publier une notification.
<shell:SystemTray.ProgressIndicator>
<shell:ProgressIndicator IsIndeterminate="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
Text="{Binding BusyMessage}" />
</shell:SystemTray.ProgressIndicator>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<toolkit:ToggleSwitch IsChecked="{Binding NextBusy, Mode=TwoWay}" Content="Next publish is busy ?" />
<Button Grid.Row="1" Content="Publish" Click="Button_Click" />
</Grid>
Pour mes notifications, je vais utiliser une classe portant le message et la valeur de IsBusy (les Tuple manquent cruellement sur WP7 !).
public class BusyNotification
{
public string BusyMessage { get; set;}
public bool IsBusy{get; set;}
}
Je vais utiliser une source observable hot (pour mémoire http://blogs.developpeur.org/leo/archive/2012/04/25/reactive-extensions-consommer-des-services-avec-rx-partie-1-cr-er-une-source-observable.aspx) puisqu’elle doit continuer à vivre en tout temps.
private Subject<BusyNotification> _notifications;
Au clic sur le bouton, je publie une notification …
private void Button_Click(object sender, RoutedEventArgs e)
{
_notifications.OnNext(new BusyNotification
{
BusyMessage = DateTime.Now.ToLongTimeString(),
IsBusy = NextBusy
});
}
Le plus intéressant maintenant, je vais observer ma source de deux manières :
- la première prend tous les messages et se contente d’afficher le progress indicator et d’y placer le bon contenu ;
- la seconde va faire un throttle sur les messages (ici de 5 secondes, c’est le temps durant lequel le message restera affiché), ainsi elle ne recevra que le dernier à être passé dans la séquence, puis on filtre sur le fait que IsBusy soit false, càd que le message doit faire disparaitre le progress indicator. Grâce au throttle, si une autre opération venait à être lancée entre temps, alors on reprend des messages avec IsBusy a true, la condition du where n’est pas satisfaite et donc le progress indicator ne disparait pas.
_notifications.ObserveOnDispatcher()
.Subscribe(n =>
{
if (!IsBusy)
IsBusy = true;
BusyMessage = n.BusyMessage;
});
_notifications.Throttle(TimeSpan.FromSeconds(5))
.Where(n => !n.IsBusy)
.ObserveOnDispatcher()
.Subscribe(n =>
{
IsBusy = false;
BusyMessage = string.Empty;
});
Vous aussi, faîtes des applis plus mieux grâce à rx !
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :