Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable ToolbarItem Xamarin.Forms

I have the following in my page:

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

The command starts an async task. I am trying to disable the control as long as the async task is still running by binding it to a boolean property as follows:

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

My issue is that there doesn't seem to be a "IsEnabled" property for ToolbarItem. Is there a way to achieve what I am trying to do using Xamarin.Forms?

like image 745
LostBalloon Avatar asked Jan 06 '15 16:01

LostBalloon


People also ask

How to disable Toolbar item in Xamarin forms?

Set IsVisible property as true to show the Toolbar, and set as false to Hide the Toolbar. The following code snippet illustrates how to achieve this method. Xaml: <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

How do I hide items on my toolbar?

To hide or display buttons on a toolbar, press the down arrow on the right of the desired toolbar and then press the Add or Remove Buttons item.

How to add Toolbar item in Xamarin forms?

The Xamarin. Forms ToolbarItem class is a special type of button that can be added to a Page object's ToolbarItems collection. Each ToolbarItem object will appear as a button in the application's navigation bar. A ToolbarItem instance can have an icon and appear as a primary or secondary menu item.


1 Answers

After the help of William and Xamarin support, I was finally able to find how functionality works.

It is a bit counter intuitive as we expect to Enable/Disable the button (ToolbarItem), but we actually have to manage the state of the command that is bound to the button. Once we understand this pattern, it makes sense.

The Command object of type ICommand, has a CanExecute property (thank you William for pointing it out) Now you don't want to access/use it directly unless it is for actually checking if the command can be executed or not.

Wherever you see fit in your code, to change the state of the command, you need to add the following line:

((Command)_myCommand).ChangeCanExecute();

This line will force the CanExecute property to be re-evaluated for the specified command.

I personally decided to add it where I track the inactivity as it made sense in my application.

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

In the View, there are no changes to be noted:

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

Now when you create the Command object is where the big work will be done. We usually use the single argument constructor as it is generally enough and it is where we define what our command does. Interestingly enough, there is a 2 parameter constructor as well where you can provide the function/action that determines the value of the CanExecute property.

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


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

Edit: I know you that technically changing the value of Inactive should happen in Run(), but for demonstration purposes...

like image 189
LostBalloon Avatar answered Oct 13 '22 20:10

LostBalloon