문제

내가 어떻게 강요 할 수 있는지 아는 사람이 있습니까? CanExecute 사용자 정의 명령을 부름 받으려면 (Josh Smith 's RelayCommand)?

일반적으로, CanExecute UI에서 상호 작용이 발생할 때마다 호출됩니다. 무언가를 클릭하면 명령이 업데이트됩니다.

조건이있는 상황이 있습니다 CanExecute 무대 뒤에서 타이머로 켜지거나 끄고 있습니다. 이것은 사용자 상호 작용에 의해 주도되지 않기 때문에 CanExecute 사용자가 UI와 상호 작용할 때까지 호출되지 않습니다. 최종 결과는 내 것입니다 Button 사용자가 클릭 할 때까지 활성화/비활성화 상태로 유지됩니다. 클릭 후 올바르게 업데이트됩니다. 때때로 Button 활성화 된 것으로 나타 났지만 사용자가 클릭하면 발사 대신 비활성화로 변경됩니다.

타이머가 영향을 미치는 속성을 변경할 때 코드의 업데이트를 강요하려면 어떻게해야합니까? CanExecute? 나는 발사를 시도했다 PropertyChanged (INotifyPropertyChanged) 영향을 미치는 속성에 CanExecute, 그러나 그것은 도움이되지 않았습니다.

예 XAML :

<Button Content="Button" Command="{Binding Cmd}"/>

뒤에있는 코드 예제 :

private ICommand m_cmd;
public ICommand Cmd
{
    if (m_cmd == null)
        m_cmd = new RelayCommand(
            (param) => Process(),
            (param) => EnableButton);

    return m_cmd;
}

// Gets updated from a timer (not direct user interaction)
public bool EnableButton { get; set; }
도움이 되었습니까?

다른 팁

나는 오래 전에 CommandManager.invalidateRequerySugged ()를 알고 있었지만 그것을 사용했지만 때로는 효과가 없었습니다. 나는 마침내 이것이 왜 그런지 알아 냈습니다! 다른 행동과 마찬가지로 던지지 않더라도 메인 스레드에서 호출해야합니다.

배경 스레드에서 호출하는 것은 작동하는 것처럼 보이지만 때로는 UI를 비활성화합니다. 나는 이것이 누군가가 누군가를 돕기를 바랍니다. 그리고 방금 낭비한 시간을 구해줍니다.

그것에 대한 해결 방법은 바인딩입니다 IsEnabled 재산으로 :

<Button Content="Button" Command="{Binding Cmd}" IsEnabled="{Binding Path=IsCommandEnabled}"/>

그런 다음 뷰 모델 에서이 속성을 구현하십시오. 또한 유닛 테스트가 명령이 아닌 속성으로 작동하는 것이 특정 시점에서 명령을 실행할 수 있는지 확인하기가 더 쉬워집니다.

나는 개인적으로 더 편리하다고 생각합니다.

아마도이 변형은 당신에게 적합 할 것입니다 :

 public interface IRelayCommand : ICommand
{
    void UpdateCanExecuteState();
}

구현:

 public class RelayCommand : IRelayCommand
{
    public event EventHandler CanExecuteChanged;


    readonly Predicate<Object> _canExecute = null;
    readonly Action<Object> _executeAction = null;

   public RelayCommand( Action<object> executeAction,Predicate<Object> canExecute = null)
    {
        _canExecute = canExecute;
        _executeAction = executeAction;
    }


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

    public void UpdateCanExecuteState()
    {
        if (CanExecuteChanged != null)
            CanExecuteChanged(this, new EventArgs());
    }



    public void Execute(object parameter)
    {
        if (_executeAction != null)
            _executeAction(parameter);
        UpdateCanExecuteState();
    }
}

간단한 사용 :

public IRelayCommand EditCommand { get; protected set; }
...
EditCommand = new RelayCommand(EditCommandExecuted, CanEditCommandExecuted);

 protected override bool CanEditCommandExecuted(object obj)
    {
        return SelectedItem != null ;
    }

    protected override void EditCommandExecuted(object obj)
    {
        // Do something
    }

   ...

    public TEntity SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;

            //Refresh can execute
            EditCommand.UpdateCanExecuteState();

            RaisePropertyChanged(() => SelectedItem);
        }
    }

XAML :

<Button Content="Edit" Command="{Binding EditCommand}"/>

팁에 감사드립니다. 다음은 BG 스레드에서 UI 스레드로 호출하는 마샬링 방법에 대한 약간의 코드입니다.

private SynchronizationContext syncCtx; // member variable

생성자에서 :

syncCtx = SynchronizationContext.Current;

백그라운드 스레드에서 Requery를 트리거하려면 :

syncCtx.Post( delegate { CommandManager.InvalidateRequerySuggested(); }, null );

도움이되기를 바랍니다.

- 마이클

단일 Galasoft.mvvmlight.commandwpf.relaycommand 만 업데이트하려면 사용할 수 있습니다

mycommand.RaiseCanExecuteChanged();

그리고 저에게는 확장 방법을 만들었습니다.

public static class ExtensionMethods
    {
        public static void RaiseCanExecuteChangedDispatched(this RelayCommand cmd)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { cmd.RaiseCanExecuteChanged(); }));
        }

        public static void RaiseCanExecuteChangedDispatched<T>(this RelayCommand<T> cmd)
        {
            System.Windows.Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => { cmd.RaiseCanExecuteChanged(); }));
        }
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top