UISlider不会更新到绑定的ViewModel属性

时间:2014-01-24 23:05:06

标签: ios xamarin mvvmcross

我有一个UISeekbar和一个位于MvxView内的UILabel

        _currentPositionText = new UILabel { TextColor = UIColor.White };
        _seekBar = new UISlider
            {
                MinValue = 0,
                Continuous = true,
                AutoresizingMask = UIViewAutoresizing.FlexibleWidth
            };
        _seekBar.TouchDown += OnTouchDown;
        _seekBar.TouchUpInside += OnTouchUpInside;
        _seekBar.TouchDragInside += OnDragInside;

我正在设置绑定如下

        set.Bind(_seekBar).For(sb => sb.Value).To(vm => _viewModel.CurrentPositionMsec);
        set.Bind(_seekBar).For(sb => sb.MaxValue).To(vm => _viewModel.DurationMsec);
        set.Bind(_currentPositionText).To(vm => vm.CurrentPositionText);

如果我在get的{​​{1}}内添加一些跟踪代码,我可以看到属性每秒更新一次(如预期的那样)。

注意:同样的方法也只需将毫秒格式化为TimeSpan即可更新CurrentPositionMsec

CurrentPositionText的绑定正在按预期更新,但_currentPositionText不会更新滑块位置。

预期结果是滑块每秒更新一次,基于_seekBar

我在Android中使用以下绑定工作,Android和iOS共享相同的viewModel。

CurrentPositionMsec

我没有正确设置吗?这“应该”工作AFAIK。

2 个答案:

答案 0 :(得分:2)

重新排序绑定似乎不会产生任何更好的结果

// binding MaxValue first doesn't fix (lambda)
set.Bind(_seekBar).For(sb => sb.MaxValue).To(vm => _viewModel.DurationMsec);
set.Bind(_seekBar).For(sb => sb.Value).To(vm => _viewModel.CurrentPositionMsec);

更改绑定以使用字符串而不是lambda DID证明可以解决问题。

// using a string did enable the bindings to work as expected.
set.Bind(_seekBar).For("MaxValue").To(vm => _viewModel.DurationMsec);
set.Bind(_seekBar).For("Value").To(vm => _viewModel.CurrentPositionMsec);

我们现在已经选择在我们的代码库中使用字符串作为标准。它确实为错误留下了空间,因为我们没有得到编译时错误,但至少它确保绑定有效。

答案 1 :(得分:0)

我在https://github.com/MvvmCross/MvvmCross-Tutorials/tree/master/ApiExamples

中的SeekView样本中添加了第二个SeekBar

此代码似乎运作良好:

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var label = new UILabel(new RectangleF(10, 100, 100, 30));
        label.Text = "Slide me:";
        Add(label);
        var seek = new UISlider(new RectangleF(110, 100, 200, 30));
        seek.MinValue = 0;
        seek.MaxValue = 100;
        Add(seek);
        var seek2 = new UISlider(new RectangleF(110, 160, 200, 30));
        seek2.MinValue = 0;
        seek2.MaxValue = 100;
        Add(seek2);
        var mirrorLabel = new UILabel(new RectangleF(110, 130, 200, 30));
        mirrorLabel.TextColor = UIColor.Blue;
        Add(mirrorLabel);

        var set = this.CreateBindingSet<SeekView, SeekViewModel>();
        set.Bind(seek).To(vm => vm.SeekProperty);
        set.Bind(seek2).To(vm => vm.SeekProperty);
        set.Bind(mirrorLabel).To(vm => vm.SeekProperty);
        set.Apply();
    }

simulator image

显然,这只会运行当前值,最大值 - 但希望这样做有用。


我唯一的建议可能是尝试重新排序绑定 - 以便在Value之前设置MaxValue。或者尝试使用固定的MaxValue,然后使用值转换器(或其他机制)来缩放当前值。