Xamarin Forms ToolbarItem doesn't change IsEnabled from XAML

3.4k Views Asked by At

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?

2

There are 2 best solutions below

3
Armin Rasoulian On

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.

0
Saimel Saez On

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.