2011-10-14 3 views
1

CanExecute 기능을 사용할 수 있도록 내 뷰에서 RoutedCommand를 사용하려고하는데, 작동시킬 수있는 유일한 방법은 DelegateCommand 프리즘에서. RoutedCommand를 사용하려고하면 버튼이 비활성 상태로 유지되고 CanExecute 함수가 사용되지 않습니다.뷰 모델의보기에서 라우트 된 명령을 사용하는 방법

XAML에 CommandBinding을 넣으려고했지만 "생성 된 코드 숨김 클래스에만 인스턴스 메서드 만 유효합니다."라는 메시지가 표시됩니다. 오류. 그 코드는 다음과 같습니다.

<Window.CommandBindings> 
    <CommandBinding Command="AddCommand" 
       Executed="my:SettingsDialogViewModel.AddCommandMethod" 
       CanExecute="my:SettingsDialogViewModel.AddCommandMethodCanExecute" /> 
</Window.CommandBindings> 

또한 코드에서 CommandBinding을 설정하려고 시도했으나 도움이되지 않습니다. 나는 코드를 뒤집어 쓰지 않는 방법, 웹상에서 발견 한 엄청나게 복잡한보고있는 것을 구현하는 방법을 모르는 것 같습니다.

도움 :

편집 주셔서 감사합니다 :

public void AddCommandMethod() 
{ 
    if (SelectedMain != null) 
    { 
     SelectedMain.IsDirty = true; 
     _faveAppList.Add(SelectedMain); 
     SelectedMain.ListOrder = _faveAppList.Count; 
     _mainAppList.Remove(SelectedMain); 
     _listDirty = true; 
    } 
} 
public void AddCommandMethodCanExecute(object sender, CanExecuteRoutedEventArgs e) 
{ 
    e.CanExecute = true; 
} 
+0

정적 방법입니까? 그렇다면'x : Static' 문법을 사용해야합니다. –

+0

아니요, 정적이 아닙니다. – Paul

+0

제공 한 코드로 제안 할 수있는 유일한 방법은 MVVM 웹 사이트를 다시 방문하는 것입니다. PRISM을 체크 아웃하는 것이 좋습니다. –

답변

1

적절한 MVVM 표기되지 않습니다 : 여기 내가 사용하려고 시도하고있는 방법이다. 이 작업을 수행하는 한 가지 방법을 제공 할 것입니다.

// MyView.cs 
public class MyView : UserControl 
{ 
    public MyViewViewModel ViewModel 
    { 
     get { return (MyViewViewModel) DataContext;} 
     set { DataContext = value; } 
    } 
} 

// DelegateCommand.cs 
public class DelegateCommand : ICommand 
{ 
     private readonly Predicate<object> _canExecute; 
     private readonly Action<object> _execute; 

     public DelegateCommand(Action<object> execute) 
      : this(execute, null) {} 

     public DelegateCommand(Action<object> execute, Predicate<object> canExecute) 
     { 
      _execute = execute; 
      _canExecute = canExecute; 
     } 

     public override bool CanExecute(object parameter) 
     { 
      if (_canExecute == null) 
      { 
      return true; 
      } 
      return _canExecute(parameter); 
     } 

     public override void Execute(object parameter) 
     { 
     _execute(parameter); 
     }  
} 

// MyViewViewModel.cs 
public class MyViewViewModel 
{ 
    public ICommand AddCommand {get;set;} 

    public MyViewViewModel() 
    { 
      AddCommand = new DelegateCommand (AddCommandMethod, AddCommandMethodCanExecute); 
    } 

    private void AddCommandMethod (object parameter) 
    { 

    } 

    private bool AddCommandMethodCanExecute(object parameter) 
    { 
     // Logic here 
     return true; 
    } 
} 

// MyView.xaml 

<Button Command="{Binding AddCommand}" /> 
+0

감사! 프리즘에서 CanExecute 함수를 사용하여 DelegateCommand를 사용할 수 있다는 것을 알지 못했습니다. 그것을 'DOH!' 내 부분에 순간. – Paul

+0

도와 드릴 수있어서 다행입니다. –

1

더 나은 옵션은 ICommand 인터페이스를 구현하고 구현 방법에 로직을 작성하는 것입니다. 그런 다음보기 모델은 사용자 지정 명령을 반환 할 수 있으며보기에서 바인딩 할 수 있습니다.

이렇게하면 실제 명령 구현이보기 모델과 분리되지만보기 모델 내에서 논리를 잘 구현할 수 있습니다. 이 같은

뭔가 :

public abstract class BaseCommand : ICommand 
{ 
    // needed to connect to WPF's commanding system 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public abstract bool CanExecute(object parameter); 
    public abstract void Execute(object parameter); 
} 

public class AddCommand : BaseCommand 
{ 
    private readonly MyViewModel _vm; 
    public AddCommand(MyViewModel vm) 
    { 
     this._vm = vm; 
    } 
    public override bool CanExecute(object parameter) 
    { 
     // delegate back to your view model 
     return _vm.CanExecuteAddCommand(parameter); 
    } 
    public override void Execute(object parameter) 
    { 
     _vm.ExecuteAddCommand(parameter); 
    } 
} 

public class MyViewModel 
{ 
    public ICommand AddCommand { get; private set; } 
    public MyViewModel() 
    { 
     AddCommand = new AddCommand(this); 
    } 

    public bool CanExecuteAddCommand(object parameter) 
    { 
    } 

    public void ExecuteAddCommand(object parameter) 
    { 
    } 
} 

그런 다음 바로 명령을 실행 컨트롤을 바인딩합니다.

<Button Command="{Binding AddCommand}">...</Button> 
관련 문제