2011-02-04 5 views
2

뷰 모델에서 모델 클래스를 올바르게 사용했는지 알고 싶습니다. MVVM으로 Caliburn Micro를 사용합니다.WPF MVVM - 뷰 모델 클래스의 모델 사용

첫 번째 대안입니다.

모델 클래스 :

[Export(typeof(ILogOnViewModel))] 
public class LogOnViewModel : Screen 
{ 
    public CurrentUser CurrentUser { get; set; } 

    //bind on control in view 
    public string CurrentNick 
    { 
     get { return CurrentUser.Nick; } 
     set 
     { 
      CurrentUser.Nick = value; 
      NotifyOfPropertyChange(() => CurrentNick); 
     } 
    } 

    //bind on control in view 
    public string CurrentPassword 
    { 
     get { return CurrentUser.Password; } 
     set 
     { 
      CurrentUser.Password = value; 
      NotifyOfPropertyChange(() => CurrentPassword); 
     } 
    } 
} 

두 번째 대안 :

모델 클래스 :

public class CurrentUser : IDataErrorInfo, INotifyPropertyChanged 
    { 


     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(String info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     public string Nick 
     { 
      get { return _nick; } 
      set 
      { 
       _nick = value; 
       NotifyPropertyChanged("Nick"); 
      } 
     } 

     public string Password 
     { 
      get { return _password; } 
      set 
      { 
       _password = value; 
       NotifyPropertyChanged("Password"); 
      } 
     } 
//... 
    } 
뷰 모델 클래스 모델을 사용

public class CurrentUser : IDataErrorInfo 
    { 
     public string Nick { get; set; } 
     public string Password { get; set; } 
//... 
    } 

뷰 모델 클래스에

사용 모델 클래스 : 더 나은보기에서 해당 모델을 캡슐화하기 때문에

[Export(typeof(ILogOnViewModel))] 
public class LogOnViewModel : Screen 
{ 
    //bind on UI control 
    public CurrentUser CurrentUser { get; set; } 
} 
+0

딥 속성 바인딩을 사용하여 첫 번째 방법을 상당히 단축 할 수 있습니다. 즉, 'CurrentUser' "CurentUser_Nick"(CurrentUser_Password에 대해 동일)의 'Nick'문자열에 바인딩하는 요소의 이름을 지정합니다. 그러면 'CurrentNick'및 'CurrentPassword'속성은 필요하지 않습니다 (NotifyOfPropertyChange를 CurrentUser에 추가합니다.) – EluciusFTW

답변

0

두 번째 접근 방법으로 시작하는 것이 좋습니다. 반복적 인 브리징 속성을 많이 입력하지 않아도됩니다. 뷰 모델에 래핑되어야하는 프로퍼티가있는 경우 해당 프로퍼티에 대해 뷰를 바인딩 한 다음 뷰의 바인딩을 업데이트하십시오. 모델과 뷰 모델 모두 IDataErrorInfo 및 INotifyPropertyChanged를 구현할 수 있습니다. 후자는 모델의 일부 로직이 속성에 변경 사항을 전달할 때 매우 유용합니다. 기본 클래스를 통해 이러한 인터페이스를 구현하면 ModelBase와 ViewModelBase 추상 클래스를 모두 가질 수 있습니다.이 클래스는 전자 클래스에서 파생됩니다.

+0

MVVM이 아니므로, MVVM에 대해 작성된 거의 모든 지침을 위반하게 될 것이며, 결코 ViewModel이 Model에서 상속받지 못할 것입니다. – decyclone

+0

@decyclone : 내가보기에 모델을 직접 참조해서는 안된다고 말했을 때 대답에서 강조한 하나의 지침을 어겼다는 것을 의미한다고 생각합니다. 다른 곳에서 언급 한 것을 보았지만 MVVM에 필수적인 것은 아닙니다. – HappyNomad

+0

참조를 위해이 기사를보십시오 : http://msdn.microsoft.com/en-us/magazine/dd419663.aspx 그리고 얼마나 많은 지침이 깨 졌는지 스스로 결정하십시오. – decyclone

5

첫 번째 대안은 더 나은 것입니다. 뷰 모델 변경 및 오류의 사용자 인터페이스를 통지 오브젝트해야하기 때문에
그러나 당신은 뷰 모델IDataErrorInfoINotifyPropertyChanged를 구현해야합니다.

+0

그래서 뷰 ​​모델 클래스에 IDataErrorInfo를 구현하는 것이 더 좋습니다. –

+0

네, 물론 WPF에서는 바인딩에서 ValidatesOnDataErrors = True를 설정할 수 있으며, 자동으로 제공되는 오류 정보를 사용합니다 그 속성 이름에 대한 ViewModel – Botz3000

5

첫 번째 방법을 선호합니다. 그 이유는 다음과 같습니다.

  • ModelView에 액세스 할 수 없습니다.
  • 이론 상으로는, 은 View에 바인딩되어야하는 모든 속성을 Model에서 감싸거나/정면으로 처리합니다. View의 기능을 용이하게하고 코드를 코드에 넣지 못하도록하는 데 필요한 추가 속성, 컬렉션 및 명령을 추가합니다.
  • IDataErrorInfoINotifyPropertyChangedView이 아닌 ViewModel을 촉진한다. ViewViewModel과 통신하기 때문에 ViewModel 안에 있어야합니다.
1

접근 방식을 사용합니다. 두 번째 방법을 사용하는 샘플 응용 프로그램을 찾고 있다면 WPF Application Framework (WAF) 프로젝트가 흥미로울 수 있습니다.