由于标题明确定义,我想在Action
中执行命令之前在我的视图中运行ViewModel
。
假设我们的NavigationDrawer
包含两种或更多种商品类型(例如NavigationItem
和ExpandableItem
)。 每个项目都绑定到相应ViewModel
上的命令。
现在我想:
NavigationItem
命令之前关闭抽屉。ExpandableItem
的动画,不要关闭抽屉。我尝试了以下方法:
public class MvxInteractiveCommand : MvxCommandBase, IMvxCommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public MvxInteractiveCommand(Action execute)
: this(execute, null)
{
}
public MvxInteractiveCommand(Action execute, Func<bool> canExecute)
{
_canExecute = canExecute;
_execute = execute;
Delay = 0;
}
/// <summary>
/// Delay in milliseconds to execute the action. Default is zero means immediate execution
/// </summary>
public int Delay { get; set; }
public object InteractData { get; set; }
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute();
}
public bool CanExecute()
{
return CanExecute(null);
}
public void Execute(object parameter)
{
if (CanExecute(parameter))
{
Mvx.Resolve<IMvxMessenger>().Publish(new CommandExecutingMessage(this) { Data = InteractData });
if (Delay == 0)
_execute();
else
Task.Delay(200).ContinueWith(obj => _execute());
}
}
public void Execute()
{
Execute(null);
}
}
public class CommandExecutingMessage : MvxMessage
{
public CommandExecutingMessage(object sender)
: base(sender)
{
}
public object Data { get; set; }
}
NavigationSimpleItem.cs :
public class NavigationSimpleItem : MvxNavigatingObject
{
private readonly IMvxCommand _clickCommand;
public NavigationSimpleItem(string caption, int id, Action doCommand, Func<bool> canDoCommand = null)
{
...
if (doCommand == null)
throw new ArgumentNullException("doCommand");
_clickCommand = new MvxInteractiveCommand(doCommand, canDoCommand);
}
public override IMvxCommand ClickCommand
{
get { return _clickCommand; }
}
...
}
MainView.cs :
public class MainView : MvxActivity
{
private MvxSubscriptionToken _token;
public MainView()
{
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.MainView);
}
protected override void OnViewModelSet()
{
base.OnViewModelSet();
_token = Mvx.Resolve<IMvxMessenger>().SubscribeOnMainThread<CommandExecutingMessage>(e =>
{
DrawerWrapper.CloseDrawer();
});
}
}
注意:如您所见,我使用Messenger Plugin在View
和ViewModel
之间进行互动。它适用于我的第一个需求,即在每个项目点击上运行一个简单的Action
。
但是,我的观点需要知道点击了哪个项以及其状态是什么。 我还想要更复杂的场景,例如等待UI动作在命令执行之前完成(类似this answer)。