[.net] WPF-CommandBindings를 통해 명령이 ‘CanExecute’를 다시 평가하도록하는 방법

나는이 Menu각각의 경우 MenuItem계층 구조에서 그 한 Command속성은 설정 RoutedCommand내가 정의한합니다. 연관된 것은 각각의 활성화 된 상태를 제어하는 CommandBinding평가를위한 콜백을 제공합니다 .CanExecuteMenuItem

이것은 거의 작동합니다. 메뉴 항목은 처음에 올바른 활성화 및 비활성화 상태로 나타납니다. 그러나 CanExecute콜백에서 사용 하는 데이터가 변경되면이 새로운 상태가 UI에 반영되도록 콜백에서 결과를 다시 요청하는 명령이 필요합니다.

에 공개 방법이있을 나타나지 않습니다 RoutedCommand또는 CommandBinding이합니다.

콜백은 클릭하거나 컨트롤에 입력 할 때 다시 사용됩니다 (마우스 오버로 인해 새로 고침이 발생하지 않기 때문에 입력시 트리거되는 것 같습니다).



답변

이 책에서 가장 예쁘지는 않지만 CommandManager를 사용하여 모든 명령 바인딩을 무효화 할 수 있습니다.

CommandManager.InvalidateRequerySuggested();

MSDN에 대한 추가 정보보기


답변

나중에 이것을 만나는 사람에게는; MVVM 및 Prism을 사용하는 경우 Prism의 DelegateCommand구현은 이를 수행 ICommand하는 .RaiseCanExecuteChanged()방법을 제공합니다 .


답변

CommandManager.InvalidateRequerySuggested();성능이 저하되어 사용할 수 없었습니다.

내가 사용하고 MVVM 도우미 외모가 아래처럼 ‘의 위임 명령을, (나는 그것을 우리 REQ에 대한 약간 불통있다). 당신은 command.RaiseCanExecuteChanged()VM 에서 전화해야합니다

public event EventHandler CanExecuteChanged
{
    add
    {
        _internalCanExecuteChanged += value;
        CommandManager.RequerySuggested += value;
    }
    remove
    {
        _internalCanExecuteChanged -= value;
        CommandManager.RequerySuggested -= value;
    }
}

/// <summary>
/// This method can be used to raise the CanExecuteChanged handler.
/// This will force WPF to re-query the status of this command directly.
/// </summary>
public void RaiseCanExecuteChanged()
{
    if (canExecute != null)
        OnCanExecuteChanged();
}

/// <summary>
/// This method is used to walk the delegate chain and well WPF that
/// our command execution status has changed.
/// </summary>
protected virtual void OnCanExecuteChanged()
{
    EventHandler eCanExecuteChanged = _internalCanExecuteChanged;
    if (eCanExecuteChanged != null)
        eCanExecuteChanged(this, EventArgs.Empty);
}


답변

자신의 클래스를 구현 한 롤을 구현 ICommand한 경우 많은 자동 상태 업데이트를 잃을 수 있으므로 필요한 것보다 수동으로 새로 고침해야합니다. 또한 고장날 수 있습니다 InvalidateRequerySuggested(). 문제는 간단한 ICommand구현으로 새 명령을에 연결하지 못한다는 것 CommandManager입니다.

해결책은 다음을 사용하는 것입니다.

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void RaiseCanExecuteChanged()
    {
        CommandManager.InvalidateRequerySuggested();
    }

이 방법으로 가입자는 CommandManager수업 대신 연결하고 명령 상태 변경에 올바르게 참여할 수 있습니다.


답변

명령에 대한 속성 종속성을 처리하는 솔루션을 구현했습니다. 여기 링크는 https : //.com/a/30394333/1716620

덕분에 다음과 같은 명령을 갖게됩니다.

this.SaveCommand = new MyDelegateCommand<MyViewModel>(this,
    //execute
    () => {
      Console.Write("EXECUTED");
    },
    //can execute
    () => {
      Console.Write("Checking Validity");
       return PropertyX!=null && PropertyY!=null && PropertyY.Length < 5;
    },
    //properties to watch
    (p) => new { p.PropertyX, p.PropertyY }
 );


답변

이것이 나를 위해 일한 것입니다 : CanExecute를 XAML의 Command 앞에 두십시오.


답변