如何在 Xamarin 表单中将 Slider 数据绑定到 Viewmodel 属性?

How to databind a Slider to Viewmodel property in Xamarin forms?

我是 Xamarin 表单的新手,使用它才几个月。我有一个 Xamarin 表单应用程序,它将与 Android 和 iOS 一起使用,并且正在使用 MVVM 结构。我的 ViewModel 中有一个 ObservableCollection 个对象,我正在使用扩展 StackLayout 的自定义转发器视图进行迭代,在 DataTemplate 内部我有一个自定义条目 class扩展将其 Text 属性绑定到对象的 Value 属性(可空双精度)的 Entry。

我接下来要做的是,如果我添加到模型中的某个布尔值的值为真,则修改模板以隐藏 Entry 标记,然后显示 Slider 和一个 Label,以显示 Slider.

的值

到目前为止,我已经能够将 Maximum/Minimum 属性绑定到我的 Viewmodel 中的属性,这很棒,但是每当我尝试绑定 Value 属性 到 Slider,我的 XAML 不会加载,而且我没有收到任何错误。我还需要实现仅允许用户滑过给定 'increment'(.1、1、2 等)的功能。我想滑动 Slider,一旦用户停止滑动,Value 属性 就会被设置并存储在模型中。如果已经存在一个值,我还需要它来预加载,但是我可以稍后再访问这两个值。

我想我做错了。我曾尝试搜索许多不同的示例,但我终生无法弄清楚。

这是我的 XAML 在 slider/label

中的样子
<Slider x:Name="slider" Value="{Binding Value}"
          Maximum="{Binding VM.Question.NumericMaxValue}"/>
   <Label x:Name="displayLabel"  
          Text="{Binding Source={x:Reference slider},  Path=Value,
          StringFormat='The slider value is {0:F0}'}" 
          HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />

我的模型的简化版本,因为我不想把我不应该放的代码放在那里。

public class MyItemModel
{
    private double? _value;

 public double? Value
   {
       get { return _value; }
       set
       {
           if (_value != value)
           {
               _value = value;


               if (!FormatAsTime)
               {
                   if (VM.Question.NumericMaxValue != -1 && Value > VM.Question.NumericMaxValue)
                   {
                       Value = VM.Question.NumericMaxValue;
                       return;
                   }
                   if (Value < VM.Question.NumericMinValue)
                   {
                       Value = VM.Question.NumericMinValue;
                       return;
                   }

                   RaisePropertyChanged(() => Value);
                   RaisePropertyChanged(() => HasValue);

                   SpinDownCommand.RaiseCanExecuteChanged();
                   SpinUpCommand.RaiseCanExecuteChanged();
               }
               else
               {
                   RaisePropertyChanged(() => Value);
                   RaisePropertyChanged(() => HasValue);
               }

               VM.UpdateCanGoNext();
           }
       }
   }
}

根据您输入的代码(缺少一些关键部分), 但我认为你应该使用 TwoWay binding:

<Slider x:Name="slider" 
    Value="{Binding Value, Mode=TwoWay}"
    Maximum="{Binding VM.Question.NumericMaxValue}"
    />

您也不需要为您的 属性 使用 Nullable<double>(正如@jason 提到的那样),因为滑块控件始终有一个值。

以及为什么您的第二个绑定 (Maximum 属性) 等于“VM.Question...”? Value 绑定不一样吗? 即:

Value="{Binding VM.Value, Mode=TwoWay}" -- ??

要仅在控件的缩略图完成 "move" 时更新值,您应该使用响应式扩展。 它允许您操纵事件和 select "last" 系列之一,例如:

Rx for Xamarin forms presentation

我让你看看更多细节...