如何使用Android + MVVMCross中的参数将按钮绑定到Cmd

时间:2014-02-21 18:01:36

标签: xamarin.android mvvmcross

我有一个非常简单的应用程序,它依赖于MVVMCross + Xamarin Android。

我已经能够在ViewModel中创建一个WP8应用程序LoginView(用户名+密码+提交按钮),该应用程序绑定到带有参数的Cmd(这将是我的密码)。现在我尝试用Android做同样的事情。如何在我的LoginView的axml文件中表达CommandParameter(视图的另一个字段)?

    public class LoginViewModel : MvxViewModel
{
    private readonly ILoginService _loginService;

    public LoginViewModel(ILoginService loginService)
    {
        _loginService = loginService;
    }

    private string _username;
    public string Username
    { 
        get { return _username; }
        set { _username = value; RaisePropertyChanged(() => Username); }
    }

    private string _error;
    public string Error {
        get { return _error; }
        set { _error = value; RaisePropertyChanged(() => Error); }
    }

    #region LoginCmd
    private MvxCommand<string> _loginCmd;
    public ICommand LoginCmd
    {
        get
        {
            _loginCmd = _loginCmd ?? new MvxCommand<string>(DoLoginCmd);
            return _loginCmd;
        }
    }

    private void DoLoginCmd(string password)
    {
        try
        {
            _loginService.Login(Username, password);
            ShowViewModel<ProjectsListViewModel>();
        }
        catch (SecurityException ex)
        {
            Error = ex.Message;
        }
    }
    #endregion
}

1 个答案:

答案 0 :(得分:4)

有关常规命令参数绑定,请参阅Using MvxCommand With CommandParameter binding

为了绑定到View中的值,我的一般答案是不要

MvvmCross不支持ElementName或RelativeSource类型绑定源。

而是所有绑定都是ViewModel / DataContext

对于您的应用示例,您可以轻松地将密码绑定到ViewModel中的属性 - 就像使用UserName

一样
评论讨论后

更新

如果由于Xaml安全问题导致Password是特殊情况,那么您可以尝试的一些选项是:

  • 您可以使用AttachedProperties解决这些安全问题 - 请参阅http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html等链接了解详情

  • 您可以在Android和iOS上绑定Password属性,然后使用Tibet绑定语法将Click事件与ViewModel绑定的CommandParameter绑定 - 类似于Click CommandParameter(LoginCmd, Password)

    < / LI>
  • 您可以使用基于ViewModel的逻辑来使用参数传入密码或(当为空时)ViewModel密码属性(password = password ?? Password;

  • 您可以使用代码隐藏或自定义控件绑定技巧来使命令参数有效...例如你可以:

    • 从Button继承LoginButton
    • 向LoginButton
    • 添加SetPasswordEditText(EditText text)方法
    • 向LoginButton添加PasswordClick ICommand属性并使其触发
    • 使用一些代码隐藏来连接UI以在命令时提供密码
    • 这可能看起来像

 public class LoginButton : Button
 {
    public LoginButton(Context c, IAttributeSet a) : base(c,a) {
       this.Click += (s,e) => {
         if (LoginClick == null) return;
         if (PasswordEditText == null) return;
         if (LoginClick.CanExecute(PasswordEditText.Text))
           LoginClick.Execute(PasswordEditText.Text);
       }
    }

    public ICommand LoginClick {get;set;}
    public EditText PasswordEditText {get;set;}
 }

 // codebehind in OnCreate as:
 var l = FindViewById<LoginButton>(Resource.Id.the_login_button);
 var p = FindViewById<EditText>(Resource.Id.the_password_box);

 l.PasswordEditText = p;

 // Axml is:
 <LoginButton 
    local:MvxBind="LoginClick LoginCmd"
    android:... etc />