Commands' canExecute isn't evaluated

Emon Haque 3,176 Reputation points
2021-02-02T07:54:37.06+00:00

In my MainPage.xaml I've these:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:VM="clr-namespace:Emon"
             x:Class="Emon.MainPage">
    <ContentPage.BindingContext>
        <VM:MainVM/>
    </ContentPage.BindingContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackLayout Margin="20,20,20,0">
            <Entry Placeholder="First Name" Text="{Binding FirstName}"/>
            <Entry Placeholder="Last Name" Text="{Binding LastName}" />
            <Button Text="Change Full Name" Command="{Binding MyCommand}"/>
        </StackLayout>
        <ListView Grid.Row="1" ItemsSource="{Binding Names}"/>
    </Grid>
</ContentPage> 

and in the MainVM.cs these:

public class MainVM : INotifyPropertyChanged
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ObservableCollection<string> Names { get; set; }
    public Command MyCommand { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    public MainVM()
    {
        MyCommand = new Command(setName, canSetName);
        Names = new ObservableCollection<string>();
    }
    void setName()
    {
        Names.Add(FirstName + " " + LastName);
        FirstName = string.Empty; LastName = null;
        OnPropertyChanged(nameof(FirstName));
        OnPropertyChanged(nameof(LastName));
    }
    bool canSetName() => !string.IsNullOrWhiteSpace(FirstName) && !string.IsNullOrWhiteSpace(LastName);
    void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

In WPF I've used UpdateSourceTrigger=PropertyChanged in TextBox but there's no such thing in Entry so even if I type in those Entries canSetName isnt called and as a result the Button remains disabled.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,366 questions
0 comments No comments
{count} votes

Accepted answer
  1. JarvanZhang 23,961 Reputation points
    2021-02-02T11:35:53.173+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    The return value of the canSetName Func cannot by updated automatically. Try adding a bool property in the MainVM class to receive the result of !string.IsNullOrWhiteSpace(FirstName) && !string.IsNullOrWhiteSpace(LastName) code. Detect the property changed event of the FirstName and LastName property to update the value of the bool property.

    Check the code:

       public class MainVM : INotifyPropertyChanged  
       {  
           public ObservableCollection<string> Names { get; set; }  
           public Command MyCommand { get; set; }  
           public MainVM()  
           {  
               MyCommand = new Command(setName, canSetName);  
               Names = new ObservableCollection<string>();  
           }  
           void setName()  
           {  
               Names.Add(FirstName + " " + LastName);  
               FirstName = string.Empty; LastName = null;  
           }  
           bool canSetName()  
           {  
               return Result;  
           }  
         
           public string firstName;  
           public string FirstName  
           {  
               get  
               {  
                   return firstName;  
               }  
               set  
               {  
                   if (firstName != value)  
                   {  
                       firstName = value;  
                       Result = !string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(LastName) ? true : false;  
                       OnPropertyChanged(nameof(FirstName));  
                   }  
               }  
           }  
         
           public string lastName;  
           public string LastName  
           {  
               get  
               {  
                   return lastName;  
               }  
               set  
               {  
                   if (lastName != value)  
                   {  
                       lastName = value;  
                       Result = !string.IsNullOrWhiteSpace(value) && !string.IsNullOrWhiteSpace(FirstName) ? true : false;  
                       OnPropertyChanged(nameof(LastName));  
                   }  
               }  
           }  
         
           public bool result;  
           public bool Result  
           {  
               get  
               {  
                   return result;  
               }  
               set  
               {  
                   if (result != value)  
                   {  
                       result = value;  
                       MyCommand?.ChangeCanExecute();  
                       OnPropertyChanged(nameof(Result));  
                   }  
               }  
           }  
         
           void OnPropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));  
           public event PropertyChangedEventHandler PropertyChanged;  
       }  
    

    Best Regards,

    Jarvan Zhang


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.