【问题标题】:MvxItemTemplate ItemClick BindingMvxItemTemplate ItemClick 绑定
【发布时间】:2015-01-09 16:57:00
【问题描述】:

我在 MvxListView 上有以下绑定

        <Mvx.MvxListView
            android:id="@+id/listGroups"
            android:layout_height="fill_parent"
            android:layout_width="fill_parent"
            android:layout_below="@+id/layoutGroupPadder"
            android:dividerHeight="7dp"
            android:divider="@drawable/list_divider"
            local:MvxItemTemplate="@layout/list_group"
            local:MvxBind="ItemsSource AvailableGroups; ItemClick GroupSelectedCommand" />

MvxItemTemplate如下

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res/xxxx.xxxx"
    android:orientation="horizontal"
    android:background="@color/white"
    android:layout_width="fill_parent"
    android:layout_height="63dp">
    <TextView
        android:id="@+id/groupsGroupName"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:textSize="18dp"
        android:gravity="center"
        android:layout_margin="7dp"
        android:textColor="@color/verydarknavy"
        local:MvxBind="Text Name" />
    <RelativeLayout
        android:id="@+id/layoutGroupGroupCount"
        android:orientation="horizontal"
        android:layout_width="90dp"
        android:layout_height="fill_parent"
        android:layout_centerInParent="true">
        <TextView
            android:id="@+id/groupsSubGroupCount"
            android:layout_width="50dp"
            android:layout_height="fill_parent"
            android:textSize="16dp"
            android:gravity="center"
            android:layout_margin="7dp"
            android:textColor="@color/hblue"
            android:layout_toLeftOf="@+id/imageArrowGrp"
            local:MvxBind="Text SubGroupCount" />
        <ImageView
            android:src="@drawable/YellowArrowRight"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_margin="7dp"
            android:layout_alignParentRight="true"
            android:id="@+id/imageArrowGrp" />
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/layoutGroupItemCount"
        android:orientation="horizontal"
        android:layout_width="90dp"
        android:layout_height="fill_parent"
        android:layout_marginRight="14dp"
        android:layout_alignParentRight="true"
        android:fitsSystemWindows="false">
        <TextView
            android:id="@+id/groupsVehicleCount"
            android:layout_width="50dp"
            android:layout_height="fill_parent"
            android:textSize="16dp"
            android:gravity="center"
            android:layout_margin="7dp"
            android:textColor="@color/hblue"
            android:layout_toLeftOf="@+id/imageArrowItem"
            local:MvxBind="Text VehicleCount" />
        <ImageView
            android:src="@drawable/YellowArrowRight"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:layout_margin="7dp"
            android:id="@+id/imageArrowItem" />
    </RelativeLayout>
</RelativeLayout>

当 ItemClick 发生时 GroupSelectedCommand 正确触发:)

但是,我想根据用户在项目中触摸的位置触发 2 个不同的命令。我需要区分哪些 TexViews 已被触摸(SubGroupCount 或 VehicleCount)

我尝试将 MvxListView 中的绑定更改为

local:MvxBind="ItemsSource AvailableGroups" />

并将与 MvxItemTemplate 的绑定更改为

 local:MvxBind="Text SubGroupCount; ItemClick GroupSelectedCommand " />

 local:MvxBind="Text VehicleCount; ItemClick ItemSelectedCommand " />

我为命令 ItemSelectedCommand 创建了必要的处理。

不幸的是它没有触发任何一个命令。

是否可以从一个模板触发单独的命令,如果可以,如何将它们绑定到 MvxItemTemplate 中的不同控件?

【问题讨论】:

    标签: xamarin.android mvvmcross


    【解决方案1】:

    要完成此操作,您需要有两个单独的命令绑定到行内的视图。

    将此添加到您希望单独点击的两个相对布局中:

    local:MvxBind="Click OpenFirstCommand"
    

    现在您需要访问列表绑定的视图模型,而不是行本身的视图模型。您可以采取多种方法来解决这个问题。

    1. 将 RowViewmodel 包装到包装器项中。有关更多详细信息,请参阅:Binding button click in ListView template MvvMCross

    2. 使用值转换器将 Row 包装到包装器项目中。更多信息:How to binding list item to whether it is contained in another collection

    我个人会选择转换器,因为它可以让您的代码更干净。转换器可能如下所示:

     public class ListWrapperValueConverter : MvxValueConverter
            {
                public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
                {
                    IEnumerable items = value as IEnumerable;
    
                    IList<CellWrapperViewModel<Item>> cellWrapperItems = items.OfType<Item>().Select(x => new CellWrapperViewModel<Item>(x, (BaseViewModel)parameter)).ToList();
    
                    ObservableCollection<CellWrapperViewModel<Item>> itemsList = new ObservableCollection<CellWrapperViewModel<Item>> (cellWrapperItems);
    
                    // If the old collection was observable, forward the triggers, happening on the old one to the new collection.
                    if (value as ObservableCollection<Item> != null) {
                        ObservableCollection<Item> documents = value as ObservableCollection<Item>;
    
                        documents.CollectionChanged += (object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) => {
                            switch (e.Action) {
                            default:
                                itemsList.SwitchTo (documents.Select (x => new CellWrapperViewModel<Item> (x, (BaseViewModel)parameter)).ToList ());
                                break;
                            }
                        };
                    }
    
                    return itemsList;
                }
            }
    

    包装器是:

    public class CellWrapperViewModel<T>
    {
        public T Item { get; set; }
    
        public BaseViewModel ViewModel { get; set; }
    
        public CellWrapperViewModel(T item, BaseViewModel viewModel)
        {
            Item = item;
            ViewModel = viewModel;
        }
    }
    

    您的 MvxListView 绑定将是:

    local:MvxBind="ItemsSource ListWrapper(Items, .)"
    

    行内命令的转换器:

    public class OpenFirstCommandValueConverter : MvxValueConverter<CellWrapperViewModel<Item>, MvxCommand>
        {
            protected override MvxCommand Convert(CellWrapperViewModel<Item> value, Type targetType, object parameter, CultureInfo culture)
            {
                BaseViewModel viewModel = value.ViewModel;
                Item item = value.Item;
    
                return new MvxCommand(() => { viewModel.OptionCommand.Execute((Item)item); });
            }
        }
    

    如果你这样做了,布局的绑定会变成这样:

    local:MvxBind="Click OpenFirstCommand(.)"
    local:MvxBind="Click OpenSecondCommand(.)"
    

    有关此问题的更多信息也在 mvvmcross GitHub 上:https://github.com/MvvmCross/MvvmCross/issues/35

    【讨论】:

    • Martijn,感谢您的帮助。我只是在我的应用程序中处理另一个功能领域,我会尽快完成并调查您提出的解决方案。再次感谢您!!
    猜你喜欢
    • 2016-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 2018-06-23
    相关资源
    最近更新 更多