【问题标题】:Binding views to ICommand.CanExecute将视图绑定到 ICommand.CanExecute
【发布时间】:2013-12-04 22:59:46
【问题描述】:

是否可以将视图属性绑定到 ICommand.CanExecute?

例如,我希望能够在触摸视图中执行类似的操作:

this
    .CreateBinding(SignInWithFacebookButton)
    .For(b => b.Enabled)
    .To((SignInViewModel vm) => vm.SignInWithFacebookCommand.CanExecute)
    .Apply();

我已经阅读了How to use CanExecute with Mvvmcross,但不幸的是它跳过了问题而只是提出了另一种实现方式。

【问题讨论】:

    标签: mvvmcross


    【解决方案1】:

    一种方法是使用您自己的继承自 UIButton 的自定义按钮。

    对于 Android,我手头有一个实现 - 它是:

    public class FullButton : Button
    {
        protected FullButton(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
            Click += OnClick;
        }
    
        public FullButton(Context context) : base(context)
        {
            Click += OnClick;
        }
    
        public FullButton(Context context, IAttributeSet attrs) : base(context, attrs)
        {
            Click += OnClick;
        }
    
        public FullButton(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
        {
            Click += OnClick;
        }
    
        private IDisposable _subscription;
    
        private object _commandParameter;
        public object CommandParameter
        {
            get { return _commandParameter; }
            set
            {
                _commandParameter = value;
                UpdateEnabled();
            }
        }
    
        private ICommand _command;
        public ICommand Command
        {
            get { return _command; }
            set
            {
                if (_subscription != null)
                {
                    _subscription.Dispose();
                    _subscription = null;
                }
    
                _command = value;
    
                if (_command != null)
                {
    
                    var cec = typeof (ICommand).GetEvent("CanExecuteChanged");
                    _subscription = cec.WeakSubscribe(_command, (s, e) =>
                        {
                            UpdateEnabled();
                        });
                }
    
                UpdateEnabled();
            }
        }
    
        private void OnClick(object sender, EventArgs eventArgs)
        {
            if (Command == null)
                return;
    
            if (Command.CanExecute(CommandParameter))
                Command.Execute(CommandParameter);
        }
    
        private void UpdateEnabled()
        {
            Enabled = ShouldBeEnabled();
        }
    
        private bool ShouldBeEnabled()
        {
            if (_command == null)
                return false;
    
            return _command.CanExecute(CommandParameter);
        }
    }
    

    这可以绑定为:

    <FullButton
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Show Detail"
        local:MvxBind="Command ShowDetailCommand; CommandParameter CurrentItem" />
    

    对于 iOS,我希望使用相同类型的技术...从 UIButton 继承并使用 TouchUpInside 而不是 Click - 但恐怕我没有此代码我现在。

    【讨论】:

    • UIButton 的默认命令绑定在哪里/如何处理?我很乐意用这种行为来补充它,因为它似乎被多次请求了。
    • @StefanFisk 我无法让它在 iOS 中工作。我继承自UIButton,实现了上面的代码,但不确定如何进行实际绑定。有什么指点吗?
    • 不怕。一开始我在视图模型上使用了一个单独的 bool 属性,但后来我用 ReactiveUI 中的那些绑定替换了所有绑定,因为我是 Rx 的忠实粉丝。
    • @StefanFisk 您是否将 ReactiveUI 与 MvvmCross 一起使用或代替 MvvmCross?
    • 到目前为止,但我希望将来删除其中一个以使应用程序更苗条。
    猜你喜欢
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多