Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Forms ToolbarItem doesn't change IsEnabled from XAML

I'm facing a problem with ToolbarItem and IsEnabled property when trying to turn it on/off from XAML using triggers. ToolbarItem doesn't support triggers, so what I do is to create a Button (a hidden one) which supports triggers and then bind Button.IsEnabled to ToolbarItem.IsEnabled; here is the sample code:

    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="tlbSave" Text="Save" Clicked="Handle_Clicked">
            <ToolbarItem.IsEnabled>
                <Binding Source="{x:Reference btnTest}" Path="IsEnabled" />
            </ToolbarItem.IsEnabled>
        </ToolbarItem>
    </ContentPage.ToolbarItems>

    <ContentPage.Content>

        <StackLayout Padding="10" VerticalOptions="CenterAndExpand">

            <Entry x:Name="txtTest" HorizontalOptions="FillAndExpand" />

            <Button x:Name="btnTest" Text="HIDDEN" IsEnabled="false" HorizontalOptions="FillAndExpand">
                <Button.Triggers>
                    <MultiTrigger TargetType="Button">
                        <MultiTrigger.Conditions>
                            <BindingCondition Binding="{Binding Source={x:Reference txtTest}, Path=Text.Length,
                                                           Converter={convert:IsPositiveIntegerConverter}}" Value="true" />
                        </MultiTrigger.Conditions>

                        <Setter Property="IsEnabled" Value="True" />
                    </MultiTrigger>
                </Button.Triggers>
            </Button>

        </StackLayout>

    </ContentPage.Content>

If you try this piece of code you will see how btnTest gets enable/disable when txtTest.Text has some value. But it isn't affecting tlbSave.IsEnabled property.

However, this work perfect in code behind when I set tlbSave.IsEnabled into btnText.PropertyChanged EventHandler

btnTest.IsVisible is false, I'm just showing it up for testing purposes.

Any idea about how to deal with this?

like image 930
Saimel Saez Avatar asked Mar 10 '19 15:03

Saimel Saez


2 Answers

This is because of the IsEnabled property of ToolbarItem is read-only.

If you just set IsEnabled property of a toolbar item in your XAML to false or true, you will get the following exception at runtime.

System.InvalidOperationException: The BindableProperty "IsEnabled" is readonly.

And if you take a look at Microsoft's documentation, you will notice that you cannot directly set IsEnabled property of a toolbar item.

For disabling a toolbar item, the suggested way is to use a command and it's CanExecute.

like image 151
Armin Rasoulian Avatar answered Nov 11 '22 13:11

Armin Rasoulian


I found out a way to solve this problem, at least a way better than implementing OnPropertyChange for btnTest

    <ContentPage.ToolbarItems>
        <ToolbarItem x:Name="tlbSave" Text="Save" Clicked="Handle_Clicked" />
    </ContentPage.ToolbarItems>

    <ContentPage.Content>

        <StackLayout Padding="10" VerticalOptions="CenterAndExpand">

            <Entry x:Name="txtTest" HorizontalOptions="FillAndExpand" />

            <Button x:Name="btnTest" Text="HIDDEN">
                <Button.Triggers>
                    <MultiTrigger TargetType="Button">
                        <MultiTrigger.Conditions>
                            <BindingCondition Binding="{Binding Source={x:Reference txtTest}, Path=Text.Length,
                                                           Converter={convert:IsPositiveIntegerConverter}}" Value="true" />
                        </MultiTrigger.Conditions>

                        <Setter Property="IsEnabled" Value="True" />
                    </MultiTrigger>
                </Button.Triggers>

                <Button.IsEnabled>
                    <Binding Source="{x:Reference tlbSave}" Path="IsEnabled" Mode="OneWayToSource" />
                </Button.IsEnabled>
            </Button>

        </StackLayout>

    </ContentPage.Content>

Then set btnTest.IsEnabled = false; inside constructor and everything will go as smooth as I want.

like image 26
Saimel Saez Avatar answered Nov 11 '22 14:11

Saimel Saez