Отключить ToolbarItem Xamarin.Forms

На моей странице есть следующее:

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

Команда запускает асинхронную задачу. Я пытаюсь отключить элемент управления, пока задача async все еще выполняется, привязывая его к логическому свойству следующим образом:

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

Моя проблема заключается в том, что для ToolbarItem не существует свойства IsEnabled. Есть ли способ достичь того, что я пытаюсь сделать, используя Xamarin.Forms?

Ответы

Ответ 1

После помощи Уильяма и Хамарина я наконец смог найти, как работает функциональность.

Это бит счетчик интуитивно понятен, так как мы ожидаем, что Enable/Disable кнопка (ToolbarItem), но мы фактически должны управлять состоянием команды, связанной с кнопкой. Как только мы понимаем этот шаблон, это имеет смысл.

Объект Command типа ICommand имеет свойство CanExecute (спасибо, Уильям, указав его) Теперь вы не хотите получать доступ к нему напрямую, если только это не проверяет, может ли команда быть выполнена или нет.

Где бы вы ни находились в вашем коде, чтобы изменить состояние команды, вам нужно добавить следующую строку:

((Command)_myCommand).ChangeCanExecute();

Эта строка приведет к переопределению свойства CanExecute для указанной команды.

Я лично решил добавить его, где я отслеживаю бездействие, поскольку это имеет смысл в моем приложении.

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

В представлении изменений не должно быть отмечено:

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

Теперь при создании объекта Command будет выполняться большая работа. Обычно мы используем конструктор одиночных аргументов, как это обычно бывает, и именно там мы определяем, что делает наша команда. Интересно, что существует и 2 конструктора параметров, где вы можете предоставить функцию/действие, которая определяет значение свойства CanExecute.

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


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

Изменить: я знаю, что технически изменение значения Inactive должно происходить в Run(), но для демонстрационных целей...

Ответ 2

В этом примере нужно удалить, а не отключить, но также может быть удобно.

    ToolbarItem delToolbar;       

    ...

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

Ответ 3

То, что я научился делать в таких ситуациях, выглядит следующим образом:

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;
}

недостаток: это оставляет элемент панели инструментов в нормальном состоянии, и пользователи могут продолжать использовать его.

вверх: это не позволит выполнять одновременные задачи OnRunCommand, что хорошо.

Если вы хотите отключить кнопку, показывая отключенное изображение, вы должны создать рендерер.

Если вы не хотите показывать элемент панели инструментов во время выполнения задачи, подумайте об удалении элемента панели инструментов со страницы и повторной добавке позже.