我有一个非常简单的应用程序,它依赖于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
}
答案 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)
您可以使用基于ViewModel的逻辑来使用参数传入密码或(当为空时)ViewModel密码属性(password = password ?? Password;
)
您可以使用代码隐藏或自定义控件绑定技巧来使命令参数有效...例如你可以:
SetPasswordEditText(EditText text)
方法
PasswordClick
ICommand属性并使其触发
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 />