Dienstag , 21 Mai 2019

Windows Azure Mobile Services – Busy Indicator für Windows Store Apps

Windows Azure Mobile Services - Busy IndicatorNichts ist schlimmer für den Benutzer einer Anwendung bzw. App, als vor dem Gerät zu sitzen und nichts scheint zu passieren.
Deshalb wird heute die "Let's Talk" Windows Store App mit einem Busy Indicator erweitert.
Wer neu zu meiner WIndows Azure Mobile Services Serie hinzugekommen ist, sollte sich vorher jedoch ansehen wie der Mobile Service angelegt, die Windows Store App erstellt und eine serverseitige Eingabevalidierung implementiert worden ist…

Ein HttpMessageHandler für den Busy Indicator

Um sich in die Client-Server Kommunikation des MobileServiceClient-Objektes einklinken zu können, muss zuerst eine Klasse erstellt werden, die von der abstrakten Klasse HttpMessageHandler ableitet.

Genauer gesagt muss diese neue Klasse von der DelegatingHandler-Klasse ableiten, da sie in ihrer SendAsync-Methode wiederum SendAsync aufrufen muss.

Somit erreicht man den gewünschten Effekt, dass die Nachrichten nur durchgereicht und nicht endgültig verarbeitet werden.

Eine einfache Variante des Busy-Handlers könnte dann wie folgt aussehen: 

public class BusyHandler : DelegatingHandler
{
  private int _callCount;
  private readonly Action<bool> _busyIndicator;

  public BusyHandler(Action<bool> busyIndicator)
  {
    _busyIndicator = busyIndicator;
  }

  protected override async Task<HttpResponseMessage> SendAsync(
    HttpRequestMessage request, CancellationToken cancellationToken)
  {
    // update the count by one in a single atomic operation. 
    // If we get a 1 back, we know we just went 'busy'
    var outgoingCount = Interlocked.Increment(ref _callCount);
    if (outgoingCount == 1)
    {
      _busyIndicator(true);
    }

    var response = await base.SendAsync(request, cancellationToken);

    // decrement the count by one in a single atomic operation.
    // If we get a 0 back, we know we just went 'idle'
    var incomingCount = Interlocked.Decrement(ref _callCount);
    if (incomingCount == 0)
    {
      _busyIndicator(false);
    }

    return response;
  }
}

 

Änderungen am ViewModel

Damit in der View der Busy Indicator ein- bzw. ausgeblendet werden kann, muss als nächstes das ViewModel entsprechend erweitert werden.

Dazu habe ich eine IsBusy-Eigenschaft im Interface hinzugefügt …

public interface IMainPageViewModel
{
  ObservableCollection Messages { get; }
  String MessageText { get; set; }
  Message SelectedMessage { get; set; }

  Boolean IsBusy { get; }

  DelegateCommand SendMessageCommand { get; }
  DelegateCommand DeleteMessageCommand { get; }
  DelegateCommand RefreshCommand { get; }
}

 

… und diese entsprechend implementiert.

private Boolean _isBusy;
public Boolean IsBusy
{
  get { return _isBusy; }
  set { SetProperty(ref _isBusy, value); }
}

 

Danach kann der BusyHandler zur Kommunikationspipeline des MobileServiceClient-Objektes hinzugefügt werden.

Dazu stellt die MobileServiceClient-Klasse den entsprechenden Konstruktor zur Verfügung:

_mobileServiceClient = new MobileServiceClient(
  App.MobileServiceUrl,
  App.MobileServiceKey,
  new BusyHandler(busy => IsBusy = busy));

 

Änderungen an der View

Zu guter Letzt muss in der View nur noch der entsprechende XAML Code hinzugefügt und an die IsBusy-Eigenschaft des ViewModels gebunden werden:

<Border Grid.ColumnSpan="2" Grid.RowSpan="3" 
        Visibility="{Binding IsBusy, 
        Converter={StaticResource BooleanToVisibilityConverter}}">
  <ProgressRing IsActive="true" Style="{StaticResource ProgressRingStyle}" />
</Border>

 

Für lesbareren Code, und zur Wiederverwendbarkeit in weiteren Views, bietet sich außerdem an die Style-Einstellungen des ProgressRing-Controls auszulagern:

<Style x:Name="ProgressRingStyle"  TargetType="ProgressRing">
  <Setter Property="HorizontalAlignment" Value="Center" />
  <Setter Property="VerticalAlignment" Value="Center" />
  <Setter Property="Foreground" Value="{StaticResource AccentColor}" />
  <Setter Property="Width" Value="100" />
  <Setter Property="Height" Value="100" />
</Style>

 

Wie geht es weiter?

Im nächsten Teil dieser Serie wird die Windows Store App mit einer Microsoft-Account-Authentifizierung erweitert.
Außerdem werden die Benutzer nur noch ihre eigenen Nachrichten löschen können.

 



Verwendete Bildquellen:
© Corinna Dumat / PIXELIO