2015-01-06 4 views
14

У меня есть следующие в моей странице:Отключить ToolbarItem 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?

+0

Заметь, я попытался заменить «ToolbarItem» с «Button» и с треском провалились: «Тип объекта Xamarin.Forms.Button не может быть преобразован в целевой тип: Xamarin.Forms.ToolbarItem». – LostBalloon

+0

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

ответ

14

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

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

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

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

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

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

+1

Мой код не работает с этим образцом. Это действительно отключает кнопку или просто не позволяет выполнить код? У вас есть полная выборка этой реализации? Благодарю. – rubStackOverflow

+1

Он делает оба (отключить кнопку & избегать выполнения). На какой платформе вы работаете? Я тестировал на iOS и Android. Кроме того, я знаю, что возникла проблема, когда порядок ToolbarItem был установлен в Secondary, где вы не могли видеть разницу между включенными или нет, но код все равно не будет выполнен, если отключен. – LostBalloon

+1

Я добавил объявление свойства для MyCommand к ответу, чтобы полностью закрыть цикл. – LostBalloon

0

Что я научился делать в этих ситуациях заключается в следующем:

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

Да, я думал об этом как о возможном «наихудшем сценарии», но я бы действительно не хотел нарушить работу пользователя с помощью кнопки. Я подумал о том, чтобы дать всплывающее окно, которое говорит им быть терпеливыми, поскольку задача уже запущена, хотя я бы скорее ее отключил. Я был удивлен этим самым основным упущением для предмета, который действует как кнопка. – LostBalloon

+0

ToolbarItem может иметь свойство IsEnabled BindableProperty в Xamarin Forms 1.3.0, теперь я думаю об этом. Я бы попробовал. –

+0

К сожалению, похоже, что это не так. – LostBalloon

1

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

ToolbarItem delToolbar;  

    ... 

     delToolbar = new ToolbarItem 
     { 
      Order = ToolbarItemOrder.Primary,     
      Text = "delete",    
      Command = new Command(async() => 
      {          
       ToolbarItems.Remove(delToolbar); 
      }) 
     }; 
     ToolbarItems.Add(delToolbar); 
Смежные вопросы