简体   繁体   中英

Caliburn command evaluation only fired once

I'm trying to enable a button on my view using Caliburns 'Can' convention for view model property evaluation.

View (excerpt)

<PasswordBox PasswordChanged="PasswordBox_OnPasswordChanged" Grid.Row="1" Grid.Column="1" />
...
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
    <Button Content="Cancel" cal:Message.Attach="[Event Click] = [Action Cancel]" />
    <Button Content="Login" cal:Message.Attach="[Event Click] = [Action Login]" />
</StackPanel>

Code-behind

private void PasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
{
    if (DataContext != null)
        ((dynamic) DataContext).Password = ((PasswordBox) sender).Password;
}

ViewModel

public class LoginSplashViewModel : Screen
{

    private string _username;
    private string _password;

    public string Username
    {
        get { return _username; }
        set
        {
            _username = value;
            NotifyOfPropertyChange();
        }
    }

    public string Password
    {
        get { return _password; }
        set
        {
            _password = value;
            NotifyOfPropertyChange();
        }
    }

    public LoginSplashViewModel()
    {
        DisplayName = "Login";
    }

    public bool CanLogin()
    {
        return  !string.IsNullOrEmpty(_username) || 
                !string.IsNullOrEmpty(_password);
    }

    public void Login()
    {
        TryClose(true);
    }

    public void Cancel()
    {
        TryClose(false);
    }

}

However the 'CanLogin()' method is only fired exactly once (when binding the view model to a view), and never again, thus the button staying disabled.

Am I missing something here?

 public string Password{
  get{ return _password;}
  set{
     _password = value;
     NotifyOfPropertyChange();
     NotifyOfPropertyChange(() => CanLogin);   // <--- Addition
   }
 } 

Likewise for UserName...

for what it's worth you don't have to the long form of the event either... you could do
<Button x:Name="Login" />

It is how the command is implemented in Caliburn. Basically there is a thing that can be called to force reevaluation of CanExecute methods in ICommand implementors .

Whenever there are changes that can be identified in code behind or viewModel. Also, you have an option to implement the command yourself and avoid this necessity.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM