首页 文章

Xamarin.Android和Spinner与ReactiveUI绑定

提问于
浏览
0

我正在尝试使用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; } }
    }
}

ViewModel

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


        public MainViewModel()
        {           
        }
    }
}

2 回答

  • 2

    我没有做任何Xamarin.Android开发,但总的来说你不想将有关视图的细节传递给ViewModel - 它不应该对视图有任何了解 .

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

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

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

    例如:ViewModel.Count是一个字符串View.Property是一个int绑定,如下所示:this.OneWayBind(this.ViewModel.Count,this.View.Property,count => int.Parse(count));

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

  • 0

    我已经说过我已经提供了有关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
            {
    

相关问题