【问题标题】:Xamarin.Android and Spinner binding with ReactiveUIXamarin.Android 和 Spinner 与 ReactiveUI 绑定
【发布时间】:2017-11-06 11:04:28
【问题描述】:

我正在尝试在 Xamarin.Android 应用程序中使用 ReactiveUI 绑定到 Spinner。要将项目添加到Spinner,我需要使用ArrayAdapter。但是ArrayAdapter 需要Android.Content.Context。我应该将它传递给 ViewModel 吗?

任何人都知道用 Xamarin.Android 编写的应用程序,它使用 ReactiveUI,我可以从哪里获得灵感? ReactiveUI 文档仅引用了为 iOS 编写的示例应用程序。

查看

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView
        android:id="@+id/Label"
        android:text="Zařízení:"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <Spinner
        android:id="@+id/Devices"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/Label"/>

    <Button
        android:id="@+id/EditCommand"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/Devices"
        android:text="Edit"/>
</RelativeLayout>

活动

namespace Test.Droid
{
    [Activity(Label = "Test.Droid", MainLauncher = true)]
    public class MainActivity : ReactiveActivity, IViewFor<MainViewModel>
    {
        public Spinner Devices { get; private set; }

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

            SetContentView(Resource.Layout.Main);
            ViewModel = new MainViewModel();
            this.WireUpControls();

            // Bindings

            this.Bind(this.ViewModel, ) // ?
        }


        private MainViewModel _viewModel;
        public MainViewModel ViewModel
        { get => _viewModel; set { this.RaiseAndSetIfChanged(ref _viewModel, value); } }

        object IViewFor.ViewModel
        { get => ViewModel; set { ViewModel = (MainViewModel)value; } }
    }
}

视图模型

namespace Test.Droid.ViewModels
{
    public class MainViewModel : ReactiveObject
    {
        // How to databind Spinner Devices ?


        public MainViewModel()
        {           
        }
    }
}

【问题讨论】:

    标签: c# data-binding xamarin.android reactiveui


    【解决方案1】:

    我没有做过任何 Xamarin.Android 开发,但通常你不想将有关视图的详细信息传递到 ViewModel - 它不应该知道有关视图的任何信息。

    我会将项目列表公开为一个集合(例如IList&lt;Item&gt;)并在绑定上使用转换器来创建一个ArrayAdapter

    this.OneWayBind(this.ViewModel.Devices, this.View.Property, devices => new ArrayAdapter(devices));
    

    this.View.Property 应该指的是设备列表更改时更改的属性。第三个参数 (devices =&gt; new ArrayAdapter()) 从 ViewModel 接收属性作为参数,然后返回一个可以在 this.View.Property 上设置的值。

    例如:

    • ViewModel.Countstring
    • View.Propertyint

    像这样绑定:

    this.OneWayBind(this.ViewModel.Count, this.View.Property, count => int.Parse(count));
    

    第三个参数可以是函数或 lambda,它接受 ViewModel 属性类型的参数并返回视图属性类型的值。

    【讨论】:

      【解决方案2】:

      我说过我会提供有关 Stackoverflow 的任何反馈,但无论如何……我们有一系列绑定扩展,其中一个是用于 Spinner 的。在典型用法中它看起来像这样

              // bind the options for the distance 
              this.BindSpinner(ViewModel,
                  vm => vm.TravelLimitSelected,
                  vm => vm.CurrentTravelLimit,
                  vm => vm.TravelLimitChoices.Distances,
                  f => f.travelLimitSpinner,
                  (items) =>
                          new ActionSpinnerAdapter<DistanceChoiceModel>((c, p) => new DistanceLimitViewHost(c, p), items));
      

      在这种情况下,扩展方法看起来像

      public static IDisposable BindSpinner<TView, TViewModel, TCommandProp, TSpinnerViewModel>(
                   this TView view,
                   TViewModel viewModel,
                   Expression<Func<TViewModel, TCommandProp>> viewModelCommandName,
                   Expression<Func<TViewModel, int>> viewModelSelectedPropertyName,
                   Expression<Func<TViewModel, IList<TSpinnerViewModel>>> viewModelSourceItemsName,
                   Expression<Func<TView, Spinner>> spinnerControl, Func<IList<TSpinnerViewModel>, ISpinnerAdapter> adapterFactory) where TViewModel : RxViewModel
                   where TCommandProp : ICommand
                   where TView : class, IViewFor<TViewModel>
                   where TSpinnerViewModel : class
              {
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-05
        • 2017-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多