Forum Xamarin.Forms


The Xamarin Forums have officially moved to the new Microsoft Q&A experience. Microsoft Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

To create new threads and ask questions head over to Microsoft Q&A for .NET and get involved today.

Multitrigger - Disable button based on conditions

Hi all,

I'm trying to get a button to only be enabled if the required fields are completed. In this instance these 2 fields are a Picker for expense type and an expense value.

I've written a behaviour for the expense value like this:

public class ExpenseValueBehaviour : Behavior<Entry>
        public ExpenseValueBehaviour()


        const string valueRegex = @"^(\d+.\d{2})$|^(\d+)$";

        static readonly BindablePropertyKey IsValidPropertyKey = BindableProperty.CreateReadOnly("IsValid", typeof(bool), typeof(ExpenseValueBehaviour), false);
        public static readonly BindableProperty IsValidProperty = IsValidPropertyKey.BindableProperty;

        public bool IsValid
            get { return (bool)base.GetValue(IsValidProperty); }
            private set { base.SetValue(IsValidPropertyKey, value);}

        protected override void OnAttachedTo(Entry bindable)
            bindable.TextChanged += HandleTextChanged;

        void HandleTextChanged(object sender, TextChangedEventArgs e)
            IsValid = (Regex.IsMatch(e.NewTextValue, valueRegex, RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)));
            ((Entry)sender).TextColor = IsValid? Color.Default : Color.Red;

        protected override void OnDetachingFrom(Entry bindable)
            bindable.TextChanged -= HandleTextChanged;

And I have a NotNull converter for checking if the select item for the picker is null like this:

    public class IsNotNullConverter : IValueConverter
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            if (value != null)
                return true;
            return false;

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture){
            return null;            

These both appear to be working correctly, break points on the NotNull converter confirm this.
Then within my xaml:

            <StudyWise:NegateBooleanConverter x:Key="inverter"/>
            <StudyWise:IsNotNullConverter x:Key="notNull"/>

    <Picker x:Name="typePicker" Title="Select type" Grid.Row="0" Grid.Column="1" VerticalOptions="CenterAndExpand" 
                        ItemsSource="{Binding ExpenseTypes}" ItemDisplayBinding="{Binding Description}" SelectedItem="{Binding ExpenseType}">

                    <Label Text="Cost" Grid.Row="1" Grid.Column="0" VerticalOptions="CenterAndExpand"/>
                    <Entry Keyboard="Numeric" Text="{Binding EstimatedCost}" Grid.Row="1" Grid.Column="1" VerticalOptions="CenterAndExpand">
                          <StudyWise:ExpenseValueBehaviour x:Name="valueValidator"/>

I then have these triggers on the button:

<Button Text="Create" Command="{Binding CreateExpenseCommand}" IsEnabled="false">
                        <Style TargetType="Button">
                                <MultiTrigger TargetType="Button">
                                        <BindingCondition Binding="{Binding Source={x:Reference valueValidator}, Path=IsValid}" Value="True" />
                                        <BindingCondition Binding="{Binding Source={x:Reference typePicker}, Path=SelectedItemProperty, Converter={StaticResource notNull}}" Value="True" />
                                    <Setter Property="IsEnabled" Value="True" />

The problem is that my button is always enabled still. I know that the valueValidator is getting called and the notNull converter is by inserting break points in the relevant classes.

Not sure if it makes any difference but I'm using FreshMVVM and running Xamarin

Many thanks in advance


  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited March 2017

    Usually we use the CanExecute feature for a button with a command.
    Its part of binding. The button will enable/disable itself based on the result of the CanExecute evaluation. This way you're not micromanaging the controls. If you had 10 controls that were all wired to the same commmand, they would all disable when the CanExecute is false.

    NOTE: There is a bug when it comes to Xamarin binding: If the object of the binding evaluates to null no further processing is done and the result is always returned as true.

    I suspect this might be the source of your issue. It looks like you're trying to bind against something that may or may not be null:

    Path=SelectedItemProperty, Converter={StaticResource notNull}}

    It won't work. If the item is null the converter will never get called, won't do its evaluation and won't return anything. The result of this binding will always be true when null, and I'll bet the converter returns true when there is a value... so the end result is you always get a true out of this. If you read through the comments on that bugzilla I reported it for nearly the same type of use: I wanted the button to be disabled when a conditional object was null.

    Hey @DavidOrtinau ... Could you weigh in on this please? Back in February you said you were going to look in on this particular bugzilla along with 5 others I reported. They were months-old back in February and I've seen no movement on them still; as another month closes. Is there anything being done on this very basic functionality bug?

Sign In or Register to comment.