MvxListView从代码创建模板布局的绑定

时间:2014-02-02 20:43:32

标签: android xamarin.android mvvmcross

假设我有一个带有MvxListView的简单布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/LiivControl.Client.Droid"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Mvx.MvxListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        local:MvxBind="ItemsSource AutoListItems; ItemClick AutoListItemClicked"
        local:MvxItemTemplate="@layout/vbmvxautoviewlistitem" />
</LinearLayout>

我的项目模板布局如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/LiivControl.Client.Droid"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    android:paddingLeft="15dip">
    <TextView
        android:id="@+id/list_complex_title"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    <TextView
        android:id="@+id/list_complex_caption"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>

我想从代码隐藏中为itemtemplate中的两个textview元素指定绑定。我不确定如何最好地去做。我猜我可以在MvxListView后面的视图代码中做一些“OnViewModelSet”。我尝试了以下但是因为它无法找到控件显然无效。

protected override void OnViewModelSet()
    {
        IVbMvxAutoListViewModel vm = base.ViewModel as IVbMvxAutoListViewModel;

        TextView title = this.FindViewById<TextView>(Resource.Id.list_complex_title);
        this.CreateBinding(title).For(x => x.Text).To(vm.ListItemDescriptor.TitlePropName).Apply();

        TextView subTitle = this.FindViewById<TextView>(Resource.Id.list_complex_caption);
        this.CreateBinding(subTitle).For(x => x.Text).To(vm.ListItemDescriptor.SubTitlePropName).Apply();
        base.OnViewModelSet();
    }

我的另一个想法是以某种方式拦截itemtemplate视图的oncreate,但如果我为itemtemplate布局创建一个视图代码文件,则不会调用OnCreate。

1 个答案:

答案 0 :(得分:15)

要在代码中进行绑定,最好是:

  1. 实施自定义MvxListViewItem
  2. 实施自定义MvxAdapter以返回自定义列表视图项
  3. 实施自定义MvxListView以使用自定义MvxAdapter
  4. 未经测试,但代码大致为:

    1。实现自定义MvxListViewItem

    public class CustomListItemView
        : MvxListItemView
    {
        public MvxListItemView(Context context,
                               IMvxLayoutInflater layoutInflater,
                               object dataContext,
                               int templateId)
            : base(context, layoutInflater, dataContext, templateId)
        {
            var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
            var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
            set.Bind(control).To(vm => vm.Title);
            set.Apply();
        }
    }
    

    2。创建自定义MvxAdapter

    在此覆盖CreateBindableView

    public class CustomAdapter
        : MvxAdapter
    {
        public CustomAdapter(Context context)
            : base(context)
        {
        }
    
        protected override IMvxListItemView CreateBindableView(object dataContext, int templateId)
        {
            return new CustomListItemView(_context, _bindingContext.LayoutInflater, dataContext, templateId);
        }
    }
    

    原文:https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Droid/Views/MvxAdapter.cs#L298

    3。实现自定义MvxListView以使用适配器

    这应该简单如下:

    public class CustomListView
        : MvxListView
    {
        public CustomListView(Context context, IAttributeSet attrs)
            : base(context, attrs, new CustomAdapter(context))
        {
        }
    }
    

    只要这是在您的主UI组件中,这应该在您的axml中可用:

    <CustomListView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        local:MvxBind="ItemsSource AutoListItems; ItemClick AutoListItemClicked"
        local:MvxItemTemplate="@layout/vbmvxautoviewlistitem" />
    

    如果您的主要UI程序集中没有CustomListView,那么有一些技巧可以让MvvmCross在Setup期间选择它 - 请参阅提供自定义Android视图程序集https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup#wiki-providing-custom-views-android


    以上是执行此操作的最佳方式(IMO) - 但如果您愿意,那么只需在自定义适配器中应用绑定并在OnCreate中设置该适配器,就可以在更少的代码中执行此操作在Activity