Übung: Kommunikation zwischen einem Element und einem Renderer

Abgeschlossen

In dieser Übung senden Sie Benachrichtigungen zwischen dem Renderer und dem freigegebenen Code ohne enge Kopplung zwischen Element und Renderer.

Öffnen der Projektmappe

Diese Übung ist eine Fortsetzung der vorherigen Übung. Sie können Ihre vorhandene Projektmappe verwenden oder mit der Projektmappe aus dem Ordner exercise2final in Ihrer geklonten oder heruntergeladenen Kopie des Übungsrepositorys beginnen.

Senden einer Nachricht vom Element aus

Sie müssen die Zeichenoberfläche löschen, wenn ein Benutzer auf die Schaltfläche zum Löschen tippt. Allerdings möchten Sie keinen Verweis vom Element auf den Renderer beibehalten, darum senden Sie eine Benachrichtigung mithilfe des integrierten Messaging Centers.

  1. Öffnen Sie SketchView.cs im freigegebenen Projekt.

  2. Erstellen Sie eine öffentliche Methode mit dem Namen Clear.

  3. Rufen Sie MessagingCenter.Send mit einer Nachricht von „Clear“ auf.

    public void Clear ()
    {
        MessagingCenter.Send(this, "Clear");
    }
    
  4. Öffnen Sie MainPage.xaml.cs.

  5. Rufen Sie in der OnClearClicked-Methode die neue Clear-Methode für sketchView auf.

Abonnieren einer Nachricht im Renderer

Führen Sie diese Schritte in den einzelnen plattformspezifischen Projekten aus, die Sie unterstützen möchten:

  1. Öffnen Sie SketchViewRenderer.cs.

  2. Erstellen Sie eine neue void-Methode mit dem Namen OnMessageClear, die einen SketchView-Parameter namens sender akzeptiert. Diese Methode wird aufgerufen, wenn die Clear-Nachricht empfangen wird.

  3. Stellen Sie sicher, dass Sie nur auf Nachrichten aus dem Element reagieren, das mit dieser Instanz des Renderers verknüpft ist. Überprüfen Sie, ob der sender dem Element entspricht. Wenn dies der Fall ist, rufen Sie die Clear-Methode für Control auf.

    void OnMessageClear(SketchView sender)
    {
        if (sender == Element)
            Control.Clear();
    }
    
  4. Wechseln Sie zur OnElementChanged-Methode.

  5. Nachdem das native Steuerelement zugewiesen ist, rufen Sie MessagingCenter.Subscribe zum Abonnieren der Clear-Nachricht auf, und legen Sie OnMessageClear auf den Action-Rückruf fest.

  6. Überschreiben Sie Dispose und Unsubscribe von diesen Nachrichten aus, um Ihren Code zu bereinigen.

  7. Führen Sie die App aus, zeichnen Sie etwas, und tippen Sie anschließend auf die Schaltfläche zum Löschen.

protected override void OnElementChanged(ElementChangedEventArgs e)
{
    if (Control == null)
    {
        ...
        MessagingCenter.Subscribe<SketchView>(this, "Clear", OnMessageClear);
    }
}

protected override void Dispose(bool disposing)
{
    if (disposing)
    {
        MessagingCenter.Unsubscribe<SketchView>(this, "Clear");
    }

    base.Dispose(disposing);
}

Erstellen einer Controllerschnittstelle

Als Nächstes senden Sie eine Benachrichtigung von den plattformspezifischen Renderern an das Xamarin.Forms-Skizzenansichtselement. Um die Benachrichtigung zu senden, fügen Sie dem Element eine öffentliche Methode hinzu. Sie möchten sie jedoch nur vom Renderer aus auslösen. Um die Erkennbarkeit zu reduzieren, definieren Sie die Methode in einer Schnittstelle und implementieren sie explizit dort.

  1. Erstellen Sie im freigegebenen Projekt XFDraw eine neue öffentliche Schnittstelle mit dem Namen .

  2. Fügen Sie eine void-Methode mit dem Namen SendSketchUpdated hinzu, die keine Argumente akzeptiert.

public interface ISketchController
{
    void SendSketchUpdated();
}

Implementieren der Controllerschnittstelle

Um den freigegebenen Code zu benachrichtigen, erstellen Sie ein öffentliches Ereignis und lösen es aus.

  1. Öffnen Sie SketchView.cs im freigegebenen Projekt.

  2. Implementieren Sie explizit ISketchController.

  3. Fügen Sie einen neuen öffentlichen Ereignishandler mit dem Namen SketchUpdated hinzu.

  4. Rufen Sie in SendSketchUpdated das SketchUpdated-Ereignis auf.

class SketchView : View, ISketchController
{
    ...
    public event EventHandler SketchUpdated;

    void ISketchController.SendSketchUpdated()
    {
        if(SketchUpdated != null)
            SketchUpdated(this, EventArgs.Empty);
    }
}

Benachrichtigen des Elements

Führen Sie diese Schritte in jedem plattformspezifischen Projekt aus:

  1. Öffnen Sie SketchViewRender.cs, und suchen Sie die -Methode.

  2. Wenn das native Steuerelement instanziiert wurde, abonnieren Sie sein LineDrawn-Ereignis. Erstellen Sie eine Handlermethode mit dem Namen PaintViewLineDrawn.

  3. Wandeln Sie in der PaintViewLineDrawn-Handlermethode Element in ISketchController um, und rufen Sie die explizit definierte SendSketchUpdated-Methode auf.

protected override void OnElementChanged(ElementChangedEventArgs e)
{
    ...
    paintView.LineDrawn += PaintViewLineDrawn;
}

private void PaintViewLineDrawn(object sender, System.EventArgs e)
{
    var sketchCon = (ISketchController)Element;

    if (sketchCon == null)
        return;

    sketchCon.SendSketchUpdated();
}

Abonnieren des Ereignisses

Der letzte Schritt ist das Abonnieren des Ereignisses auf SketchView im freigegebenen Code. Sie verwenden das Ereignis, um die Schaltfläche zum Löschen zu deaktivieren, wenn die Zeichenoberfläche leer ist. Um den Aktivierungsstatus von ToolbarItem zu steuern, benötigen Sie einen Befehl. Wenn Sie mit Befehlen vertraut sind, können Sie ihn selbst implementieren. Sie können auch den bereitgestellten Code verwenden. Fügen Sie den folgenden Code MainPage.Xaml.cs im freigegebenen Projekt hinzu:

  1. Erstellen Sie eine boolesche Eigenschaft namens IsCanvasDirty mit einem Unterstützungsfeld zum Nachverfolgen des Zustands des Zeichenbereichs. Definieren Sie den Befehl, und rufen Sie ChangeCanExecute mit dem Befehl auf, wenn die IsCanvasDirty-Eigenschaft aktualisiert wird.

    public partial class MainPage : ContentPage
    {
        bool IsCanvasDirty
        {
            get { return isCanvasDirty; }
            set
            {
                isCanvasDirty = value;
    
                if (clearCommand != null)
                    clearCommand.ChangeCanExecute();
            }
        }
        bool isCanvasDirty;
    
        Command clearCommand;
        ...
    }
    
  2. Abonnieren Sie das SketchUpdated-Ereignis, und instanziieren Sie clearCommand. Weisen Sie den neuen Befehl dem trash-Symbolleistenelement zu. Der Befehl ersetzt den Ereignishandler. Löschen Sie das Clicked-Abonnement.

    public MainPage()
    {
        ...
        sketchView.SketchUpdated += OnSketchUpdated;
    
        clearCommand = new Command(OnClearClicked, () => { return IsCanvasDirty; });
    
        var trash = new ToolbarItem()
        {
            Text = "Clear",
            Icon = "trash.png",
            Command = clearCommand
        };
        ...
    }
    
  3. Abonnieren Sie im Konstruktor das SketchUpdated-Ereignis von sketchView mit der Ereignishandlermethode OnSketchUpdated. Wenn OnSketchUpdated aufgerufen wird, legen Sie IsCanvasDirty auf true fest. Wenn OnClearClicked aufgerufen wird, rufen Sie sketchView.Clear auf, und legen Sie IsCanvasDirty auf false fest.

    public MainPage()
    {
       ...
       sketchView.SketchUpdated += OnSketchUpdated;
    }
    
    void OnSketchUpdated(object sender, EventArgs e)
    {
        IsCanvasDirty = true;
    }
    
    void OnClearClicked ()
    {
        sketchView.Clear();
        IsCanvasDirty = false;
    }
    
  4. Führen Sie die App aus.

Zusammenfassung

In dieser Übung haben Sie Benachrichtigungen zwischen dem freigegebenen Element und den plattformspezifischen Renderern gesendet, ohne die Rendererinstanz eng an das Element zu koppeln. Insbesondere werden Sie den plattformspezifischen Code anweisen, die Zeichenoberfläche von der freigegebenen Benutzeroberfläche aus zu löschen, und Sie werden den freigegebenen Code benachrichtigen, wenn die Zeichenoberfläche aktualisiert wird.