[英]MvvmCross UITextField custom binding
所以我试图在MvvmCross中为UITextField实现自定义绑定,几乎与软件键盘上的 Binding'GO '键一致 - 即尝试绑定文本字段以在点击完成按钮时自动触发事件键盘(因此绑定到ShouldReturn
)。 我还需要绑定文本字段的EditingDidBegin
和EditingDidEnd
事件。 因为我绑定了多个事件,所以我创建了一个MvxPropertyInfoTargetBinding
,如下所示:
public class MyTextFieldTargetBinding : MvxPropertyInfoTargetBinding<UITextField>
{
private ICommand _command;
protected UITextField TextField
{
get { return (UITextField)Target; }
}
public MyTextFieldTargetBinding(object target, PropertyInfo targetPropertyInfo) : base(target, targetPropertyInfo)
{
TextField.ShouldReturn += HandleShouldReturn;
TextField.EditingDidBegin += HandleEditingDidBegin;
TextField.EditingDidEnd += HandleEditingDidEnd;
}
private bool HandleShouldReturn(UITextField textField)
{
if (_command == null) {
return false;
}
var text = textField.Text;
if (!_command.CanExecute (text)) {
return false;
}
textField.ResignFirstResponder();
_command.Execute(text);
return true;
}
private void HandleEditingDidBegin (object sender, EventArgs e)
{
// do something
}
private void HandleEditingDidEnd (object sender, EventArgs e)
{
// do something
}
public override MvxBindingMode DefaultMode
{
get { return MvxBindingMode.OneWay; }
}
public override void SetValue(object value)
{
var command = value as ICommand;
_command = command;
}
public override Type TargetType
{
get { return typeof(ICommand); }
}
protected override void Dispose(bool isDisposing)
{
if (isDisposing)
{
if (TextField != null)
{
TextField.ShouldReturn -= HandleShouldReturn;
TextField.EditingDidBegin -= HandleEditingDidBegin;
TextField.EditingDidEnd -= HandleEditingDidEnd;
}
}
base.Dispose(isDisposing);
}
}
我的第一个问题是:我是否正确为所有事件创建一个MvxPropertyInfoTargetBinding
? 相关地,我没有区分MvxPropertyInfoTargetBinding
和MvxTargetBinding
。 根据MVVMCross Binding decimal到UITextField删除小数点 ,前者在替换现有绑定时使用,后者用于已知属性和事件对。 我使用正确的吗?
其次(以及我的问题的真正关键),我的代码除了 SetValue
之外还有效 - 它被触发,但value
null
。 这是我在Setup
文件中的内容:
protected override void FillTargetFactories (IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories (registry);
registry.RegisterPropertyInfoBindingFactory(typeof(MyTextFieldTargetBinding), typeof(UITextField), "Text");
}
我的View
没有做任何事情 - 也许这就是问题所在?
编辑:
我的ViewModel
:
public class LoginViewModel : MvxViewModel
{
private string _username;
public string Username
{
get { return _username; }
set { _username = value; RaisePropertyChanged(() => Username); }
}
private string _password;
public string Password
{
get { return _password; }
set { _password = value; RaisePropertyChanged(() => Password); }
}
private MvxCommand _login;
public ICommand Login
{
get {
_login = _login ?? new MvxCommand(DoLogin);
return _login;
}
}
public LoginViewModel(ILoginManager loginManager)
{
_loginManager = loginManager;
}
private void DoLogin()
{
// call the login web service
}
}
在我的“视图”中,我不做任何花哨的事情(我在XIB中创建了View元素):
public override void ViewDidLoad()
{
base.ViewDidLoad ();
this.NavigationController.SetNavigationBarHidden(true, false);
var set = this.CreateBindingSet<LoginView, Core.ViewModels.LoginViewModel>();
set.Bind(usernameTextField).To(vm => vm.Username);
set.Bind(passwordTextField).To(vm => vm.Password);
set.Bind (loginButton).To (vm => vm.Login);
set.Apply();
}
没有有趣的跟踪消息。
你引用的问题 - MVVMCross绑定十进制到UITextField删除小数点 - 给出了MvxTargetBinding
和MvxPropertyInfoTargetBinding
之间差异的关键:
a non-propertyInfo-based binding
在你的情况下,因为你实际上并没有通过Reflection使用Text
属性,所以我很想不使用PropertyInfoTargetBinding并避开Text
名称 - 而只是编写一个自定义TargetBinding。
在替换现有绑定时使用前者
这绝对不是真的 - 相反,任何绑定都可以用来替换另一个绑定 - 正如另一个问题的答案所说的那样
MvvmCross运营着一个简单的“最后注册胜利”系统
有关自定义绑定的更多信息,请查看:
您当前的绑定代码要求ICommand:
public override Type TargetType
{
get { return typeof(ICommand); }
}
但是您的View代码当前将View绑定到string
:
// View
set.Bind(usernameTextField).To(vm => vm.Username);
// ViewModel
private string _username;
public string Username
{
get { return _username; }
set { _username = value; RaisePropertyChanged(() => Username); }
}
解决这个问题......
string
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.