2014-03-03 1 views
0

우리는 리본이 달린 커다란 앱을 가지고 있습니다. 리본 버튼은 모두 기본보기 모델 (기본 앱 창의 데이터 컨텍스트)에있는 명령에 바인딩됩니다.MVVM Light 만 사용하는 별도의 클래스에 구현 된 ICommand?

다양한 리본 명령에 바인딩 된 RelayCommands를 많이 만들면서 MainViewModel의 생성자가 커지기 시작합니다. 차라리 MainViewModel의 생성자에서 인라인 코드의 톤보다, 각 명령을 구현하는 별도의 수업을 선호하는 것

public MainWindowViewModel() 
    { 
     this.OpenProjectCommand = new RelayCommand(() => 
      { 
       // buncha code 
      }); 

     this.ProjectTypesCommand = new RelayCommand(() => 
      { 
       // more code 
      }); 

     this.NewSectionCommand = new RelayCommand(() => 
      { 
       // code code code... 
      }); 
     // ... only three ribbon buttons down, this is gonna get huge... 
    } 

: 그것은 다음과 같이 보입니다. (또는 OpenProject, CanOpenProject와 같은 MainViewModel에서 많은 대리자를 만든 다음 RelayCommand 생성자에 대한 참조를 전달합니다.)

단순히 CommandBase에서 ICommand를 구현 한 다음 별도의 명령을 작성하지 않는 이유는 무엇입니까? 왜냐하면 저는 this question에 따라 "표준 친화적"이되고 싶습니다.

내 명령이 별도의 클래스가되도록 사용할 수있는 표준 ICommand 구현이 있습니까?

이미 MVVM Light를 사용하고 있으므로 믹스에 MVVM 프레임 워크를 추가하지 않는 것이 좋습니다. 그러나 나는 또한 바퀴를 재발 명하고 싶지 않다.

업데이트 : MainViewModel.cs는 수십 개의 #regions 또는 명령 방법으로 어지러 울 필요가 없습니다. 확장 방법은 IMHO에 적합하지 않습니다.

+0

어떻게 명령을 생성하고 commandparameter 안에 당신이 하나의 명령의 실행 방법 안에 if 문에 의해 사용되는 조건을 지정 어떻습니까? –

+0

@devhedgehog 각 명령을 고유 한 클래스로 구분하려고하지만 설정된 MVVM 규칙 또는 MVVM Light 도구 (링크 된 질문 참조)와 반대되는 방식으로 보겠습니다. –

답변

1

내가하는 방식은 "하위 뷰 모델"이 있다는 것입니다. 예를 들어 MainViewModel의 경우 PrintCommandCancelPrintCommand이 있다고 가정 해 보겠습니다. PrinterViewModel이라는 새 클래스를 만들 수 있으며이 클래스의 인스턴스를 MainViewModel에 노출시킬 수 있습니다. PrintCommandCancelPrintCommand이이 PrinterViewModel입니다 (모듈 단위 테스트가 가능하므로 깔끔합니다). XAML에서 그런

: 또는

Command="{Binding Main.Printer.PrintCommand}" 

, 당신은 이해

new RelayCommand(() => Printer.DoSomething()) 

합니까을 할 수 있습니까?

건배 로랑

0

적어도 게터에서 만들 수 있습니다. ?? 운영자. 반환 _testCommand,하지만 여전히 널 (null) 인 경우 먼저 생성 :

http://msdn.microsoft.com/en-us/library/ms173224.aspx

이것은 기본적으로 말한다.

이렇게하면 명령이 필요할 때까지 명령이 만들어지지 않습니다! 당신의 목표는 구성 할 경우

public class TestViewModel : ViewModelBase 
{ 
    #region OpenCommand 
    private RelayCommand _testCommand; 
    public RelayCommand TestCommand { 
     get { 
      return _testCommand = _testCommand 
       ?? new RelayCommand(
        this.ExecuteOpenCommand, 
        this.CanOpenCommandExecute); 
     } 
    } 
    private void ExecuteOpenCommand() 
    { 
     // do stuff 
    } 

    private bool CanOpenCommandExecute() 
    { 
     return true; 
    } 
    #endregion 
} 

, 당신은 # 지역 및 #endregion를 사용할 수 있습니다. 그리고 우리가 말했듯이, 당신의 목표가 건설 과정을 축소시키는 것이라면, ?? 게터에서 연산자. 인라인 코드가 싫다면 getter에서 RelayCommand와 함께 private 메소드를 생성하십시오.

+0

사실, 조금 깔끔할 수도 있습니다. MainViewModel.cs가 커지지 않도록 각 명령을 자체 클래스에 구현합니다. 이 작업을 수행하는 "수락 된"방법이 있는지 궁금합니다. 내가 사용하고있는 MVVM 프레임 워크 (MVVM Light)는 자신의 ICommand 구현을 롤링하지 않고는 이것을 지원하지 않는 것 같습니다. –

+0

저에게 완벽하게 들리 네요. 또는 새 RelayCommand 작성을 피하기 위해 ... MVVM Light의 RelayCommand의 'base'생성자에서 대리자 메서드를 전달할 수 없습니까? – Mtihc

+0

'OpenProjectCommand'라는 이름의'RelayCommand' 서브 클래스를 작성합니다. 그리고'OpenProjectCommand' 클래스의'method'를'base' 생성자의 인자로 전달하십시오. – Mtihc