Reactiveui bind не работает для SeekBar.Progress

Я пытаюсь изучить reactiveui, поэтому я хотел сделать простое приложение для калькуляции чаевых для Android. ViewModel:

public class TipCalcViewModel : ReactiveObject
{
    [IgnoreDataMember] private double _subtotal;

    [DataMember]
    public double Subtotal
    {
        get { return _subtotal; }
        set { this.RaiseAndSetIfChanged(ref _subtotal, value); }
    }

    [IgnoreDataMember] private int _percentage;

    [DataMember]
    public int Percentage
    {
        get { return _percentage; }
        set { this.RaiseAndSetIfChanged(ref _percentage, value); }
    }

    [IgnoreDataMember] private readonly ObservableAsPropertyHelper<double> _tipAmount;

    [DataMember]
    public double TipAmount
    {
        get { return _tipAmount.Value; }
    }

    [IgnoreDataMember] private readonly ObservableAsPropertyHelper<double> _total;

    [DataMember]
    public double Total
    {
        get { return _total.Value; }
    }

    public TipCalcViewModel(ITipCalcService service)
    {
        _tipAmount = this.WhenAnyValue(
            x => x.Subtotal,
            y => y.Percentage,
            service.CalculateTipAmount)
            .ToProperty(this, vm => vm.TipAmount);

        _total = this.WhenAnyValue(
            x => x.Subtotal,
            y => y.Percentage,
            service.CalculateTotal)
            .ToProperty(this, vm => vm.Total);
    }
}

А Activity выглядит так:

public class TipCalcActivity : ReactiveActivity<TipCalcViewModel>
{
    public EditText SubTotal { get { return this.GetControl<EditText>(); } }
    public SeekBar Percentage { get { return this.GetControl<SeekBar>(); } }
    public TextView PercentageText { get { return this.GetControl<TextView>(); } }
    public TextView TipAmount { get { return this.GetControl<TextView>(); } }
    public TextView Total { get { return this.GetControl<TextView>(); } }

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        var service = new TipCalcService();
        ViewModel = new TipCalcViewModel(service);

        this.Bind(ViewModel, vm => vm.Subtotal, v => v.SubTotal.Text);
        //this.Bind(ViewModel, vm => vm.Percentage, v => v.Percentage.Progress);
        this.OneWayBind(ViewModel, vm => vm.Percentage, v => v.PercentageText.Text);
        this.OneWayBind(ViewModel, vm => vm.TipAmount, v => v.TipAmount.Text);
        this.OneWayBind(ViewModel, vm => vm.Total, v => v.Total.Text);

        var disposable = Observable.FromEventPattern<SeekBar.ProgressChangedEventArgs>(
            h => Percentage.ProgressChanged += h,
            h => Percentage.ProgressChanged -= h)
            .Throttle(TimeSpan.FromMilliseconds(500))
            .DistinctUntilChanged()
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(x => 
                ViewModel.Percentage = x.EventArgs.Progress);
    }
}

Итак вопросы:

  • Если я использую выше закомментированную привязку, ничего не происходит. Таким образом, свойство progress изменяется правильно, но свойство Percentage ViewModel никогда не устанавливается. Привязка работает от модели представления к представлению, но не наоборот (привязка EditText работает нормально в обоих направлениях). Как это исправить?

  • Мне удалось заставить его работать, если я создал наблюдаемое из события ProgressChanged. Но даже если бы мне пришлось сделать что-то подобное, я не уверен, правильный ли это путь. Также мне нужно избавляться от подписки, если активность уничтожена вручную или нет?

  • И последнее. Если бы я хотел изучить этот фреймворк, с чего лучше всего начать?


person Stevan Mladenovic    schedule 10.11.2014    source источник


Ответы (1)


SeekBar, скорее всего, отсутствует в списке поддерживаемых готовых элементов управления; В Android нет встроенного способа наблюдения за свойствами представления, поэтому мы должны жестко запрограммировать их как разовые. Вы можете заставить эту работу работать, если напишете что-то вроде:

var progressChanged = Observable.FromEventPattern<SeekBar.ProgressChangedEventArgs>(
        h => Percentage.ProgressChanged += h,
        h => Percentage.ProgressChanged -= h);

this.Bind(ViewModel, 
    vm => vm.Percentage, 
    v => v.Percentage.Progress, 
    signalViewUpdate: progressChanged);
person Ana Betts    schedule 10.11.2014