0

I would like to do a simple Can Execute for my login page. Here is my code:

(Email & Password are view model properties)
(ex// string email; public string Email { get {...} set {...} })

LoginPageVM
{
     Login = new AsyncCommand(OnLogin, LoginEntered())
}

public bool LoginEntered()
{
     return !string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(password);
}

The LoginEntered() in the command init gives me this error:

CS1503: Argument 2: cannot convert from 'bool' to 'System.Func<object, bool>?'

Could anybody explain how I should fix this. I would also like to eventually pass parameters with the func so if somebody could explain what is going on here that would be awesome! I understand that Func<object,bool> is a func delegate that takes in an object then returns a bool but I can't seem to figure out how to correctly return a bool.

I tried to change the syntax and got another error:

Func<object, bool> LoginEntered = (object obj) => !string.IsNullOrEmpty(email) && !string.IsNullOrEmpty(password);

This gave me more errors claiming that I can't access non-static variables:

CS0236: A field initializer cannot reference the non-static field, method, or property 'LoginPageVM.Email'

CS0236: A field initializer cannot reference the non-static field, method, or property 'LoginPageVM.Password'

To make my question clear, how would I be able to write a Can Execute for an async command with no parameters as well as one with parameters. I would also like to know how to trigger the CanExecuteChanged with the XCT/MVVM Helpers plugin syntax within my properties.

Hope to hear back from somebody soon!

Thank You in Advance!


Thanks for the fast response!

Everything in my view model is bound correctly and I have fixed my syntax error by making my method:

public bool LoginEntered(object obj)
{
     return { ... }
}

Making the method void gives me the following error:

CS0407: 'void LoginPageVM.LoginEntered(object)' has the wrong return type

The problem I'm having now is triggering the CanExecuteChanged. My properties look like this:

string email;
public string Email
{
     get => email;
     set 
     {
          SetProperty(ref email, value);
          Login.CanExecuteChanged()
     }
}

The problem is that Login.CanExecuteChanged() gives me these errors:

CS0079: The event 'ICommand.CanExecuteChanged' can only appear on the left hand side of += or -=

CS7036: There is no argument given that corresponds to the required formal parameter 'sender' of 'EventHandler

Hope to hear from you soon!

2 Answers2

0

First, LoginEntered cannot return bool, because there is nowhere to return it to. Commands always have return type void.

First change:

public void LoginEntered()

Second, when you put LoginEntered() into declaration of Command, that means "execute LoginEntered() NOW, and put the return value into what I am declaring."

But you don't want to execute LoginEntered NOW (during the constructor, while the command is being created), you want it to be executed LATER.

Second change:

Login = new AsyncCommand(OnLogin, LoginEntered);
// OR
Login = new AsyncCommand(OnLogin, () => LoginEntered());

Third, in the second syntax above, we have a place to add a parameter.

Third change:

Login = new AsyncCommand(OnLogin, (obj) => LoginEntered(obj));
...
public void LoginEntered(object obj)
{
}

obj would be from CommandParameter in the xaml that calls your Command. HOWEVER, in next section, we see this is NOT NEEDED in your case.


Fourth, you'll need to show where email and password are declared.

You mention XCT/MVVM. Bind email and password to properties in your view model. If you don't know how to do that binding, then research that topic. (That is a separate topic from your question; mvvm binding is covered extensively elsewhere.)

If you do that, then there is no need to pass them in the command.
They will be available to the command method. Just like any other property in your view model class:

Fourth change:

public string Email { get; set; }
public string Password { get; set; }
...
public void LoginEntered()
{
    ... do something with `Email` and `Password`.
}

Add to question any xaml and/or c# that uses/sets email and password.

ToolmakerSteve
  • 18,547
  • 14
  • 94
  • 196
0

I spent quite some time trying to figure it out but I finally found a video on YouTube that fixed my issue. The video can be found here: https://www.youtube.com/watch?v=Wd6ssAIdR30&t=189s

My properties look like this:

string email;
public string Email
{
     get => email;
     set 
     {
          SetProperty(ref email, value);
          ((AsyncCommand)Login).RaiseCanExecuteChanged()
     }
}

My method to evaluate Can Execute looks like this:

public bool LoginEntered(object obj)
{
     return { ... }
}