我在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个不同的命令。我需要区分哪些TexView被触摸(SubGroupCount或VehicleCount)
我尝试将MvxListView中的绑定更改为
local:MvxBind="ItemsSource AvailableGroups" />
并将与MvxItemTemplate的绑定更改为
local:MvxBind="Text SubGroupCount; ItemClick GroupSelectedCommand " />
和
local:MvxBind="Text VehicleCount; ItemClick ItemSelectedCommand " />
我为命令ItemSelectedCommand创建了必要的处理。
不幸的是,它没有触发任何命令。
是否可以从一个模板激发单独的命令,如果是,如何将它们绑定到MvxItemTemplate中的不同控件?
答案 0 :(得分:1)
要完成此任务,您需要有两个单独的命令绑定到行内的视图。
将此添加到您希望单独点击的两个相对布局中:
local:MvxBind="Click OpenFirstCommand"
现在您需要访问列表绑定的viewmodel而不是行本身的Viewmodel。您可以采取多种方法来解决这个问题。
将RowViewmodel包装到包装器项中。有关详细信息,请参阅:Binding button click in ListView template MvvMCross
使用值转换器将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;
}
}
The Wrapper将是:
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