【问题标题】:Reactiveui bind not working for SeekBar.ProgressReactiveui 绑定不适用于 SeekBar.Progress
【发布时间】:2015-01-06 23:50:34
【问题描述】:

我正在尝试学习 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 属性正在正确更改,但 ViewModel 的 Percentage 属性从未被设置。绑定是从视图模型到视图,但不是其他方式(EditText 绑定在两个方向上都可以正常工作)。如何解决这个问题?

  • 如果我从 ProgressChanged 事件创建 observable,我设法让它工作。但即使我不得不做这样的事情,我也不确定这是否是正确的方法。另外,当活动被手动销毁时,我是否必须处理订阅?

  • 最后一件事。如果我想学习这个框架,最好的开始方式是什么?

【问题讨论】:

    标签: c# android mvvm xamarin.android reactiveui


    【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2019-12-04
      • 1970-01-01
      • 2019-09-27
      • 2017-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多