MVVMCross 绑定小数到 UITextField 删除小数点 [英] MVVMCross Binding decimal to UITextField removes decimal point

查看:21
本文介绍了MVVMCross 绑定小数到 UITextField 删除小数点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将小数绑定到 UITextField 不会让您输入."在,当您键入1."时,推到源会将其删除.我明白为什么会发生这种情况,MakeSafeValue 将其转换为十进制,该十进制可以在没有."的情况下被读回,从而覆盖输入的文本.这似乎是 keyup 与 onblur 的问题,很多绑定框架都可以让您覆盖.

Binding a decimal to a UITextField does not let you put a "." in, as you type "1.", the push to source strips it out. I get why it happens, MakeSafeValue converts it to a decimal, which gets read back out without the ".", overwriting the Text entered. This seems like a keyup vs onblur issue, which a lot of binding frameworks let you override.

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

I know I could bind a string on the view model instead, but handling the EditingDidEnd instead of EditingChanged seems better. That way I could intercept ShouldEndEditing to check validity.

我应该在哪里注册我的绑定来覆盖 MvvmCross 实现?我尝试添加我的 Setup.FillTargetFactories,但它在 MvvmCross 所在的 MVXTouchBindingBuilder.FillTargetFactories 之前调用.

Where would I register my binding to override the MvvmCross implementation? I tried adding in my Setup.FillTargetFactories, but it is called before MVXTouchBindingBuilder.FillTargetFactories where the MvvmCross one is.

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

I tried a different property name, in FillTargetFactories I have:

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

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

but it does not work when I bind.

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

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

looks like MvxPropertyInfoTargetBindingFactory.CreateBinding does not work if the target does not have that property = makes sense. Does this leave me with starting at MvxTargetBinding and creating a custom binding? I hate to recreate most of the code in MvxPropertyInfoTargetBinding.

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

So, I guess the question(s) are...

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

提前致谢.

推荐答案

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

what is the syntax/location to override the default UITextField binding with mine?

如果你想简单地替换现有的绑定,那么你可以通过 RegisterPropertyInfoBindingFactory 扩展方法来实现.

If you want to simply replace the existing binding, then you can do this via the RegisterPropertyInfoBindingFactory extension method.

MvvmCross 运行一个简单的上次注册获胜"系统.

MvvmCross operates a simple 'last registered wins' system.

最简单的注册顺序是将它放在 InitializeLastChance 的末尾,在您的 Setup 中:

The easiest place your registration in order that happens last is to place it at the end of InitializeLastChance in your Setup:

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

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

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

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

how can I specify a different binding for Text with the Bind Syntax?

行:

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

不起作用,因为它试图使用名为 DidEndText 的属性 - 该属性不存在.

doesn't work because it tries to use a property called DidEndText - which doesn't exist.

解决此问题的两种可能方法是:

Two possible ways around this are:

1 子类 UITextField 提供真实属性

1 Subclass UITextField to provide a real property

   public class MyTextField : UITextField
   {
        // ctors

        public string MySpecialText
        {
            get { return base.Text; }
            set { base.Text = value; }
        }
   }

UITextField 子类化的示例显示在 N=33 视频

An example of UITextField subclassing is shown in the N=33 video

2 或者使用非基于propertyInfo的绑定

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

For known properties and event pairs this is pretty simple to do:

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 处理金钱,这可能会坚持显示所有值的小数位.

As well as your 'use a string in the ViewModel' suggestion, another possible workaround for this double-text conversion, might be to use a two-way value converter. If your UI is handling money, this could insist on displaying decimal places for all values.

这篇关于MVVMCross 绑定小数到 UITextField 删除小数点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆