MVVMCross绑定小数到UITextField删除小数点

时间:2013-07-11 21:21:30

标签: mvvm xamarin.ios xamarin mvvmcross

将小数绑定到UITextField不会让你输入“。”在输入“1”时,推送源将其剥离。我明白为什么会发生这种情况,MakeSafeValue会将其转换为小数,后者会在没有“。”的情况下读回来,覆盖输入的文本。这似乎是一个keyup vs onblur问题,很多绑定框架都允许你覆盖。

我知道我可以在视图模型上绑定一个字符串,但是处理EditingDidEnd而不是EditingChanged似乎更好。这样我就可以拦截ShouldEndEditing来检查有效性。

我会在哪里注册我的绑定以覆盖MvvmCross实现?我尝试在我的Setup.FillTargetFactories中添加,但是在MvvmCross的MVXTouchBindingBuilder.FillTargetFactories之前调用它。

我在FillTargetFactories中尝试了一个不同的属性名称:

registry.RegisterPropertyInfoBindingFactory(typeof (UITextFieldTextDidEndTargetBinding), typeof (UITextField), "DidEndText");

但是当我绑定时它不起作用。

set.Bind(textField).For("DidEndText").To(vm => vm.GMoney);

看起来像MvxPropertyInfoTargetBindingFactory.CreateBinding如果目标没有那个属性=没有意义。这是否让我从MvxTargetBinding开始并创建自定义绑定?我讨厌在MvxPropertyInfoTargetBinding中重新创建大部分代码。

所以,我猜问题是......

  • 覆盖与我的默认UITextField绑定的语法/位置是什么?
  • 如何使用绑定语法为Text指定不同的绑定?

提前致谢。

1 个答案:

答案 0 :(得分:4)

  

覆盖与我的默认UITextField绑定的语法/位置是什么?

如果您只想替换现有的绑定,则可以通过RegisterPropertyInfoBindingFactory扩展方法执行此操作。

MvvmCross运营着一个简单的“最后注册胜利”系统。

您最后注册的最简单的地方是将其放在InitializeLastChance的{​​{1}}末尾:

Setup

有关https://github.com/slodge/MvvmCross/wiki/Customising-using-App-and-Setup(正在进行中)的初始化/设置顺序的更多信息。

  

如何使用绑定语法为Text指定不同的绑定?

该行:

 protected override void InitializeLastChance()
 {
     base.InitializeLastChance();

     var factory = base.Resolve<IMvxTargetBindingFactoryRegistry>();
     factory.RegisterPropertyInfoBindingFactory(
                     typeof(MyBindingType),
                     typeof(UITextField),
                     "Text");
 }

不起作用,因为它试图使用名为 registry.RegisterPropertyInfoBindingFactory( typeof (UITextFieldTextDidEndTargetBinding), typeof (UITextField), "DidEndText"); 的属性 - 它不存在。

有两种可能的方法:

1子类DidEndText提供不动产

UITextField

public class MyTextField : UITextField { // ctors public string MySpecialText { get { return base.Text; } set { base.Text = value; } } }

中显示了UITextField子类化的示例

2或使用非基于PropertyInfo的绑定

对于已知的属性和事件对,这很简单:

public class MySpecialBinding : MvxTargetBinding
{
    public MySpecialBinding (UIEditField edit)
        : base(edit)
    {
        edit.SpecialEvent += Handler;
    }

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            var text = (UITextField)Target;
            if (text != null)
            {
                text.SpecialEvent -= Handler;
            }
        }
        base.Dispose(isDisposing);
    }

    protected override void Handler(object s, EventArgs e)
    {
        var text = (UITextField)target;
        if (text == null)
            return;
        FireValueChanged(text.Text);
    }

    public override MvxBindingMode DefaultMode
    {
        get { return MvxBindingMode.TwoWay; }
    }

    public override Type TargetType
    {
        get { return typeof(string); }
    }

    public override void SetValue(object value)
    {
        var text = (UITextField)target;
        if (text == null)
            return;
        text.Text = value;
    }
}

可以使用RegisterCustomBindingFactory

注册此特殊绑定
registry.RegisterCustomBindingFactory<UITextField>(
        "FooFlipper", 
        textField => new MySpecialBinding(textField));

之后绑定如:

set.Bind(textField).For("FooFlipper").To(vm => vm.GMoney);

会奏效。


除了'在ViewModel中使用字符串'建议之外,这种双文本转换的另一种可能的解决方法可能是使用双向值转换器。如果你的UI正在处理钱,这可能会坚持显示所有值的小数位。