ToolbarItem Command is not running

Hi all,

I have a page and view model for it. All the bound properties are working fine except the command (I don't provide all of the properties to make the post shorter :) ):

public class MyViewModel : INotifyPropertyChanged
{

    private bool isBusy;
    private bool canGoNext;

    public MyViewModel()
    {
        // ...

        this.GoToNextStepCommand = new Command(async () => await this.GoToNextStepAsync(), () => this.canGoNext);

        // ...
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public bool IsBusy
    {
        get
        {
            return this.isBusy;
        }

        set
        {
            this.isBusy = value;
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsBusy)));
        }
    }

    public ICommand GoToNextStepCommand { get; private set; }

    private async Task<IEnumerable<MyTestObject>> GoToNextStepAsync()
    {
        this.IsBusy = true;
        this.CanGoNext(false);

        /// ...

        this.CanGoNext(true);
        this.IsBusy = false;

        return data;
    }

    private void CanGoNext(bool value)
    {
        this.canGoNext = value;
        ((Command)this.GoToNextStepCommand).ChangeCanExecute();
    }
}

Here is the page:
XAML:

    <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="...MyPage">
    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="nextBtn" Order="Primary" Icon="nextIcon.png" Priority="0" Command="{Binding GoToNextStepCommand}"/> 
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="White">
            <ScrollView>
                <StackLayout Orientation="Vertical">
                    <ListView x:Name="RoadTemplates"
                  HasUnevenRows="true"
                  RowHeight="300"
                  ItemSelected="OnMenuItemSelected"
                              IsRefreshing="{Binding IsLoading, Mode=OneWay}"
                  ItemsSource="{Binding Templates}">
                        <ListView.ItemTemplate >
                            <DataTemplate>
                                <control:ExpandableViewCell 
                            Name="{Binding Data.Name}" 
                            ShortDescription="{Binding Data.ShortDescription" 
                            IconSvg="{Binding Data.ImageSvg}" 
                            FullDescription="{Binding Data.Description}"
                            IsSelected="{Binding IsSelected}"/>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </StackLayout>
            </ScrollView>
            <ContentView x:Name="bgLayer"
                                      BackgroundColor="#000000"
                                      IsVisible="{Binding IsBusy}"
                                      Opacity="0.2" />
            <Frame x:Name="frameLayer"
                                BackgroundColor="#FFFFFF"
                                HorizontalOptions="CenterAndExpand"
                                IsVisible="{Binding IsBusy}"
                                VerticalOptions="CenterAndExpand">
                <StackLayout>
                    <ActivityIndicator x:Name="indicatorLoader"
                                                    BackgroundColor="Transparent"
                                                    IsRunning="{Binding IsBusy}"
                                                    IsVisible="{Binding IsBusy}"
                                                    VerticalOptions="CenterAndExpand"
                                                    Color="#607D8B" />
                    <Label HorizontalTextAlignment="Center"
                                        Text="Loading..."
                                        TextColor="#000000"
                                        XAlign="Center" />
                </StackLayout>
            </Frame>
        </Grid>
    </ContentPage.Content>
</ContentPage>

Code:

public partial class MyPage : ContentPage
{
    private MyViewModel vm;

    public MyPage()
    {
        this.vm = new MyViewModel();
        this.InitializeComponent();
        this.BindingContext = this.vm;
        this.canGoNext = true;

        this.GoToNextStepCommand = new Command(async () => await this.GoToNextStepAsync(), () => this.canGoNext);
    }

    private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        // ...
    }
}

The command is not firing. I assume this is because of wrong place where it searches for the command. Please advice how to fix it? Btw how to display an alert from this command and how to open a new page? Should I move this command to the page class? How to bind it in this case?

Thanks a lot in advance!

Tagged:

Best Answer

  • UnexpectedPirateUnexpectedPirate RU ✭✭
    Accepted Answer

    Solved. I moved the command to the page and set Biding directly in the XAML:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        ...
             x:Name="body">
    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="nextBtn" Order="Primary" Icon="nextIcon.png" Priority="0" Command="{Binding GoToNextStepCommand, Source={x:Reference body}}"/>
    

    The important thing is to set the property (Command) before the InitializeComponent()

Answers

  • UnexpectedPirateUnexpectedPirate RUMember ✭✭
    Accepted Answer

    Solved. I moved the command to the page and set Biding directly in the XAML:

    <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        ...
             x:Name="body">
    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="nextBtn" Order="Primary" Icon="nextIcon.png" Priority="0" Command="{Binding GoToNextStepCommand, Source={x:Reference body}}"/>
    

    The important thing is to set the property (Command) before the InitializeComponent()

Sign In or Register to comment.