Как сообщить ReactiveUI об обновлении привязок (например, RaiseCanExecuteChanged())?

Как сообщить ReactiveUI об обновлении привязок?

Обычно я бы сделал что-то вроде этого:

    string _instructorNameInput;
    public string InstructorNameInput
    {
        get { return _instructorNameInput; }
        set
        {
            this.RaiseAndSetIfChanged(ref _instructorNameInput, value);
            Submit.RaiseCanExecuteChanged();
        }
    }

Однако следующее не поддерживается:

Submit.RaiseCanExecuteChanged();

В результате, как я могу принудительно обновить привязки на основе предиката CanExecute, на который опирается моя команда?

Обновлено:

public partial class FormViewModel : ReactiveObject
{
    public FormViewModel()
    {
        Submit = ReactiveCommand.Create(this.WhenAnyValue(x => x.CanSubmit));
        Submit.Subscribe(x => OnSubmit());
    }

    bool _canExecute;
    public bool CanSubmit
    {
        get { return !GetUnsatisfied().Any(); }
        set { this.RaiseAndSetIfChanged(ref _canExecute, value); } // Need to update view based on command.CanExecute state change
    }
    void OnSubmit()
    {
        var rosterInfo = new RosterInfo(new Course(CourseInput.Name),
                                        new Instructor(InstructorNameInput, InstructorIdInput));
        var repository = GetRepository();
        repository.AddCourseInfo(rosterInfo);

        Publish(REQUEST_NAVIGATION_TO_SUBMITION_CONFIRMATION, rosterInfo);
    }

    ObservableCollection<RequiredField> GetUnsatisfied()
    {
        RequiredFields.Clear();
        RequiredFields = Review();
        return RequiredFields;
    }
}

person Scott Nimrod    schedule 17.12.2015    source источник
comment
Что такое Submit? Это реактивная команда?   -  person pmbanka    schedule 17.12.2015
comment
Да. Это реактивная команда.   -  person Scott Nimrod    schedule 17.12.2015
comment
Вообще непонятно в чем у вас проблема. Не могли бы вы предоставить полный код модели представления (с конструктором, командой и свойством) и четко указать, какого поведения вы хотите добиться и какое поведение вы наблюдаете в своей программе?   -  person pmbanka    schedule 17.12.2015
comment
Я обновил пример кода. Мне нужно, чтобы мой CanExecute запускал обновление моего представления. DelegateCommand.RaiseCanExecuteChange() делает это за меня в Prism. Однако я не знаю, как это сделать с помощью ReactiveUI.   -  person Scott Nimrod    schedule 17.12.2015


Ответы (1)


Несколько проблем:

Прочитайте основы на ReactiveObject, в частности, как "Читать -Write Properties».

В вашем случае this.WhenAnyValue(x => x.CanSubmit) будет запускать обновление команды всякий раз, когда изменяется свойство CanSubmit, но это никогда не происходит, потому что вы никогда не вызываете сеттер (а у геттера есть неверный импл).

В настоящее время ваш метод GetUnsatisfied() имеет семантику «опроса», что означает, что вам нужно что-то, чтобы вызвать этот метод для обновления вашей команды. Это совсем не реактивно, вместо этого вы должны привязываться/прослушивать обновления.

Если у вас нет возможности сделать вашу логику Review() реактивной, вы можете сделать что-то вроде:

var canExec = Observable.Timer(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
                        .Select(_ => !GetUnsatisfied().Any());
Submit = ReactiveCommand.Create(canExec);
Submit.Subscribe(x => OnSubmit());

В основном имея таймер, чтобы сделать ваш опрос. (Но я настоятельно рекомендую идти дальше по реактивному пути)

person Gluck    schedule 18.12.2015