it-swarm.com.de

Deaktivieren Sie ToolbarItem Xamarin.Forms

Ich habe folgendes auf meiner Seite:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" />
</ContentPage.ToolbarItems>

Der Befehl startet eine asynchrone Task ..__ Ich versuche, das Steuerelement zu deaktivieren, solange die async-Task noch ausgeführt wird, indem es wie folgt an eine boolesche Eigenschaft gebunden wird:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" IsEnabled="{Binding MyBoolProperty}" />
</ContentPage.ToolbarItems>

Mein Problem ist, dass es anscheinend keine "IsEnabled" -Eigenschaft für ToolbarItem gibt. Gibt es eine Möglichkeit, mit Xamarin.Forms das zu erreichen, was ich versuche?

17
LostBalloon

Nach der Unterstützung von William und Xamarin konnte ich endlich herausfinden, wie die Funktionalität funktioniert.

Es ist ein wenig intuitiv, da wir die Aktivierung/Deaktivierung der Schaltfläche (ToolbarItem) erwarten, aber wir müssen tatsächlich den Status des Befehls verwalten, der an die Schaltfläche gebunden ist. Sobald wir dieses Muster verstanden haben, macht es Sinn.

Das Command-Objekt vom Typ ICommand verfügt über eine CanExecute-Eigenschaft (danke William, dass Sie es darauf hingewiesen haben). Jetzt möchten Sie nicht direkt darauf zugreifen/es verwenden, es sei denn, es wird geprüft, ob der Befehl ausgeführt werden kann oder nicht.

Wo immer Sie in Ihren Code passen, müssen Sie die folgende Zeile hinzufügen, um den Status des Befehls zu ändern:

((Command)_myCommand).ChangeCanExecute();

In dieser Zeile wird die CanExecute-Eigenschaft für den angegebenen Befehl erneut ausgewertet.

Ich habe mich entschieden, es hinzuzufügen, wenn ich die Inaktivität nachverfolgen möchte, die in meiner Bewerbung sinnvoll war.

public bool Inactive { 
    get { 
        return _inactive;
    } 
    set {
        if (_inactive != value) {
            _inactive = value;
            ((Command)_myCommand).ChangeCanExecute();
            OnPropertyChanged ();
        }
    }
}

In der Ansicht sind keine Änderungen zu beachten:

<ToolbarItem Text="Run" Command="{Binding MyCommand}" />

Wenn Sie jetzt das Befehlsobjekt erstellen, wird die große Arbeit erledigt. Wir verwenden normalerweise den Konstruktor mit einem einzigen Argument, da er im Allgemeinen ausreichend ist und wir definieren, was unser Befehl tut. Interessanterweise gibt es auch einen 2-Parameter-Konstruktor, in dem Sie die Funktion/Aktion angeben können, die den Wert der CanExecute-Eigenschaft bestimmt.

_myCommand = new Command (async () => {
                                          Inactive = false;
                                          await Run();
                                          Inactive = true;
                                      },
                                      () => {
                                          return Inactive;
                                      });


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

Edit: Ich kenne Sie, dass das Ändern des Werts von Inactive technisch in Run () erfolgen sollte, aber zu Demonstrationszwecken ...

17
LostBalloon

Was ich in diesen Situationen gelernt habe, ist wie folgt:

public Command RunCommand 
{ 
    get { return new Command(async() => await OnRunCommand()); }
}    

private bool _isRunning;

public async Task OnRunCommand() 
{
    if (_isRunning) return;
    _isRunning = true;

    // do stuff

    _isRunning = false;
}

Das downside: Das Symbolleistenelement bleibt in seinem normalen Status und Benutzer können es weiterhin antippen.

Das upside: Dies erlaubt keine gleichzeitigen OnRunCommand-Tasks, was gut ist.

Wenn Sie die Deaktivierung der Schaltfläche durch Anzeigen eines deaktivierten Bildes fortsetzen möchten, sollten Sie einen Renderer erstellen.

Wenn Sie das Symbolleistenelement nicht anzeigen möchten, während die Aufgabe ausgeführt wird, sollten Sie das Symbolleistenelement von der Seite entfernen und es später erneut hinzufügen.

1
Will Decker

Dieses Beispiel dient zum Entfernen, nicht zum Deaktivieren, kann aber auch nützlich sein.

    ToolbarItem delToolbar;       

    ...

        delToolbar = new ToolbarItem
        {
            Order = ToolbarItemOrder.Primary,                
            Text = "delete",              
            Command = new Command(async () =>
            {                                       
                ToolbarItems.Remove(delToolbar);
            })
        };
        ToolbarItems.Add(delToolbar);
1