2010-03-15 3 views
19

두 개의 텍스트 상자 (사용자 이름 및 암호)와 로그인 단추가있는 간단한 로그인 UserControl을 코딩하고 있습니다. 사용자 이름과 암호 필드가 채워져있을 때만 로그인 버튼을 활성화하고 싶습니다. 프리즘과 MVVM을 사용하고 있습니다. LoginViewModel에는 로그인 단추에 바인딩 된 LoginCommand라는 특성이 들어 있습니다. 내 ViewModel에서 CanLoginExecute() 메서드가 있지만 응용 프로그램이 다시 시작되면 다시 시작됩니다. 따라서 로그인 버튼이 활성화되지 않습니다. 내가 뭘 놓치고 있니?WPF-Prism CanExecute 메서드가 호출되지 않습니다.

<TextBox x:Name="username" 
    Text="{Binding Path=Username, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
<TextBox x:Name="password" 
    Text="{Binding Path=Password, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
<Button Content="Login" 
    cmnd:Click.Command="{Binding LoginCommand}" /> 

가 여기 내 ViewModel에

class LoginViewModel : IDataErrorInfo, INotifyPropertyChanged 
{ 
    public LoginViewModel() 
    { 
     this.LoginCommand = 
      new DelegateCommand<object>(
       this.LoginExecute, this.CanLoginExecute); 
    } 

    private Boolean CanLoginExecute(object dummyObject) 
    { 
     return (string.IsNullOrEmpty(Username) || 
       string.IsNullOrEmpty(Password)) ? false : true; 
    } 

    private void LoginExecute(object dummyObject) 
    { 
     if (CheckCredentials(Username, Password)) 
     { 
      .... 
     } 
    } 

    #region IDataErrorInfo Members 

    public string Error 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public string this[string columnName] 
    { 
     get 
     { 
      string result = null; 
      if (columnName == "Username") 
      { 
       if (string.IsNullOrEmpty(Username)) 
        result = "Please enter a username"; 
      } 
      else if (columnName == "Password") 
      { 
       if (string.IsNullOrEmpty(Password)) 
        result = "Please enter a password"; 
      } 
      return result; 
     } 
    } 

    #endregion // IDataErrorInfo Members 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion // INotifyPropertyChanged Members 

    #region Properties 

    private String _username; 
    public String Username 
    { 
     get { return _username; } 
     set 
     { 
      if (value == _username) 
       return; 
      _username = value; 
      this.OnPropertyChanged("Username"); 
     } 
    } 

    private String _password; 
    public String Password 
    { 
     get { return _password; } 
     set 
     { 
      if (value == _password) 
       return; 
      _password = value; 
      this.OnPropertyChanged("Password"); 
     } 
    } 

    public ICommand LoginCommand { get; private set; } 

    #endregion // Properties 
} 
+0

: 뭔가 프리즘 특정 Click.Command =입니다. 나는 보통

+0

예, CMND : 의 xmlns : Click.Command는 = 프리즘 특정 CMND = "CLR-네임 스페이스 : Microsoft.Practices.Composite.Presentation.Commands, 조립 = Microsoft.Practices.Composite.Presentation" 내가 사용하고 있기 때문에 Prism 's DelegateCommand, 나는 이것이 호환 가능한 명령 바인딩 메커니즘이라고 생각했다. 나는 또한 똑바로 Command = "{LoginCommand 바인딩하기"}를 시도했다 - 똑같이 작동한다. – Naresh

답변

40

바운드 컨트롤이 결코 다시 CanExecute 상태를 요구되지 않는다는 가능성이 높습니다입니다 :

여기 내 XAML입니다. CanExecute 상태를 변경하는 조건을 발견 할 때마다 DelegateCommand에서 RaiseCanExecuteChanged 메서드를 호출해야합니다. 이것은 바인딩 된 컨트롤에 CanExecute 상태를 업데이트하도록 신호를 보냅니다. RaiseCanExecuteChanged에 대한

+0

RaiseCanExecuteChanged는 매력처럼 작동합니다! 감사합니다. olli – Naresh

+18

ICommand 인터페이스를 사용했기 때문에 (RaiseCanExecuteChanged) 메소드를 찾지 못했습니다. 이 메서드는 DelegateCommand 구현에 정의되어 있으므로이를 캐스팅해야했습니다. – alf

8

코드 :

CMND 무엇
private void RaiseCanExecuteChanged() 
    { 
     DelegateCommand<object> command = LoginCommand as DelegateCommand<object>; 
     command.RaiseCanExecuteChanged(); 
    } 

    public const string UsernameProperty = "Username"; 
    private String _username; 
    public String Username 
    { 
     get { return _username; } 
     set 
     { 
      _username = value; 
      this.NotifyPropertyChanged(UsernameProperty); 
      RaiseCanExecuteChanged(); 
     } 
    } 
관련 문제