如何在执行绑定的ViewModel命令之前运行View on View

时间:2015-06-25 08:04:39

标签: c# mvvm xamarin xamarin.android mvvmcross

由于标题明确定义,我想在Action中执行命令之前在我的视图中运行ViewModel

方案

假设我们的NavigationDrawer包含两种或更多种商品类型(例如NavigationItemExpandableItem)。 每个项目都绑定到相应ViewModel上的命令。

现在我想:

  1. 在执行NavigationItem命令之前关闭抽屉。
  2. 在执行命令之前显示ExpandableItem的动画,不要关闭抽屉。
  3. 我尝试了以下方法:

    核心项目

    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; }
        }
        ...
    }
    

    Droid项目

    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 PluginViewViewModel之间进行互动。它适用于我的第一个需求,即在每个项目点击上运行一个简单的Action

    但是,我的观点需要知道点击了哪个项以及其状态是什么。 我还想要更复杂的场景,例如等待UI动作在命令执行之前完成(类似this answer)。

0 个答案:

没有答案