programing

WPF - 명령어가 명령어 바인딩을 통해 'CanExecute'를 재평가하도록 강제하는 방법

telecom 2023. 4. 20. 20:02
반응형

WPF - 명령어가 명령어 바인딩을 통해 'CanExecute'를 재평가하도록 강제하는 방법

나는 가지고 있다Menu각각 어디에MenuItem계층에는 그 기능이 있습니다.Command로 설정된 속성RoutedCommand나는 정의했다.관련지어져 있는CommandBinding를 평가하기 위한 콜백을 제공합니다.CanExecute각각의 활성화 상태를 제어합니다.MenuItem.

이거 거의 먹히네.메뉴 항목에는 처음에 올바른 활성화 및 비활성화 상태가 표시됩니다.하지만 내 데이터가CanExecute콜백은 변경을 사용합니다.이 새로운 상태를 UI에 반영하려면 콜백에서 결과를 재요구하는 명령어가 필요합니다.

에 대한 공개 방법은 없는 것 같습니다.RoutedCommand또는CommandBinding이걸 위해서.

컨트롤을 클릭하거나 입력하면 콜백이 다시 사용됩니다(마우스 오버를 해도 새로 고침이 발생하지 않으므로 입력 시 트리거되는 것 같습니다).

이 책에서 가장 예쁜 것은 아니지만 Command Manager를 사용하여 모든 명령 바인딩을 무효화할 수 있습니다.

CommandManager.InvalidateRequerySuggested();

MSDN 상세보기

나중에 이걸 접하게 될 분들을 위해, 만약 당신이 MVVM과 프리즘을 사용한다면, 프리즘의DelegateCommand실시ICommand를 제공하다.RaiseCanExecuteChanged()방법을 가르쳐 주세요.

사용할 수 없었습니다.CommandManager.InvalidateRequerySuggested();퍼포먼스에 타격을 받았기 때문에

다음과 같은 MVVM Helper의 위임 명령을 사용했습니다(필요에 맞게 조금 조정했습니다).전화해야 한다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://stackoverflow.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 }
 );

XAML 명령어 앞에 CanExecute를 붙입니다.

언급URL : https://stackoverflow.com/questions/1340302/wpf-how-to-force-a-command-to-re-evaluate-canexecute-via-its-commandbindings

반응형