it-roy-ru.com

Отключить панель инструментов элемента Xamarin.Forms

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

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

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

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

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

17
LostBalloon

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

Это немного противоречит интуиции, так как мы ожидаем включить/отключить кнопку (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, именно там будет выполнена большая работа. Обычно мы используем конструктор с одним аргументом, поскольку этого достаточно, и именно здесь мы определяем, что делает наша команда. Интересно, что также имеется конструктор с двумя параметрами, в котором вы можете предоставить функцию/действие, определяющее значение свойства CanExecute.

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


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

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

17
LostBalloon

В этих ситуациях я научился делать следующее:

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

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

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

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

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

1
Will Decker

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

    ToolbarItem delToolbar;       

    ...

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