我想在我的customlayout中绑定一个按钮点击事件,下面是我的customlayout
<?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-auto"
android:layout_width="match_parent"
android:layout_height="63dp">
<LinearLayout
android:orientation="horizontal"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:text="Accept"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/acceptBtnOnList"
android:background="@color/green_color"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textStyle="bold"
android:layout_weight="1"
android:textColor="@android:color/background_light"
local:MvxBind="Click AcceptCommand" />
</LinearLayout>
</RelativeLayout>
下面的是我的ListView布局
<?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-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/background_light">
<Mvx.MvxListView
android:id="@+id/ListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:cacheColorHint="#FFDAFF7F"
local:MvxBind="ItemsSource MyList; ItemClick ShowDetailCommand"
local:MvxItemTemplate="@layout/customlayout" />
</LinearLayout>
如上所示,我在listview布局中调用了我的customlayout
以下是我的ViewModelClass
public class ListViewModel : BaseViewModel
{
public IListService ListService { get; set; }
private MvxCommand _acceptCommand;
private ListAcceptedResult _accepted;
private MvxCommand _detailsCommand;
private ObservableCollection<MyCustomClass> _myList = new ObservableCollection<MyCustomClass>();
public ListViewModel(IListService listService)
{
ListService = listService;
}
public ObservableCollection<MyCustomClass> MyList
{
get { return _myList; }
set
{
_myList = value;
RaisePropertyChanged(() => MyList);
}
}
public ListAcceptedResult Accepted
{
get { return _accepted; }
set
{
_accepted = value;
RaisePropertyChanged(() => Accepted);
Update();
}
}
public ICommand AcceptCommand
{
get
{
IsLoading = true;
return
new MvxCommand<MyCustomClass>(
item =>
//On Success assigning the returned value from service to Accepted Property,
error => { IsLoading = false; ReportError(error.Message); }));
}
}
public async System.Threading.Tasks.Task Update()
{
//update logic
}
}
但是我无法将AcceptCommand命令绑定到我的按钮。
我知道这不起作用,因为在我的customlayout视图中我没有得到AcceptCommand命令,因为它不是对象的一部分MyCustomClass
请帮我举一些例子。
提前致谢
答案 0 :(得分:0)
如您所知,数据绑定通过直接绑定到当前ViewModel / Model来工作。除非您提供访问父项的属性,否则您无法访问父视图模型的属性或命令。
无论如何,一个选项是创建一个在绑定中使用的值转换器。此转换器将返回MvxCommand
对象,该对象在执行时将使用MvxMessenger
发布消息。
父视图模型将订阅此消息,然后执行所需的命令。
我根据Stuart Lodge的N = 02示例创建了一个示例。
https://github.com/kiliman/MvxCommandToMessage
编辑:我修改了示例以使用通用MessageToCommandValueConverter
。您现在可以在绑定中传递消息类型。您仍然需要特定的消息类型,因为MvxMessenger.Publish()
是您应用的全局消息。请参阅GitHub上的代码了解更改。
这是值转换器:
public class KittenAcceptedMessageValueConverter : MvxValueConverter<Kitten, ICommand>
{
protected override ICommand Convert(Kitten kitten, Type targetType, object parameter, CultureInfo culture)
{
return new MvxCommand(() =>
{
var messenger = Mvx.Resolve<IMvxMessenger>();
var message = new KittenAcceptedMessage(this, kitten);
messenger.Publish(message);
});
}
}
以下是您在布局中绑定它的方式。使用.
将当前对象传递给转换器。
<Mvx.MvxImageView
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_margin="10dp"
local:MvxBind="ImageUrl ImageUrl; Click KittenAcceptedMessage(.)" />
最后在ViewModel中,您将订阅此消息,并调用您的命令:
_messenger.Subscribe<KittenAcceptedMessage>(message =>
{
KittenAcceptedCommand.Execute(message.Kitten);
});
private MvxCommand<Kitten> _kittenAcceptedCommand;
public ICommand KittenAcceptedCommand
{
get
{
_kittenAcceptedCommand = _kittenAcceptedCommand ?? new MvxCommand<Kitten>(kitten =>
{
var toast = Mvx.Resolve<IToastPlugin>();
toast.Show(string.Format("You accepted {0}", kitten.Name));
});
return _kittenAcceptedCommand;
}
}
希望这有帮助。