1

将小数绑定到 UITextField 不会让您放置“。” 在中,当您键入“1.”时,对源的推送会将其删除。我明白为什么会发生这种情况,MakeSafeValue 将其转换为小数,在没有“。”的情况下将其读回,覆盖输入的文本。这似乎是一个 keyup 与 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 绑定覆盖的语法/位置是什么?
  • 如何使用 Bind 语法为 Text 指定不同的绑定?

提前致谢。

4

1 回答 1

4

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

如果你想简单地替换现有的绑定,那么你可以通过RegisterPropertyInfoBindingFactory扩展方法来做到这一点。

MvvmCross 运行一个简单的“最后注册获胜”系统。

最简单的将您的注册放在最后发生的顺序是将其放在InitializeLastChance您的末尾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中有更多关于初始化/设置顺序的信息(正在进行中)。

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

该行:

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

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

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

1UITextField提供不动产的子类

   public class MyTextField : UITextField
   {
        // ctors

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

N=33 视频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 正在处理金钱,这可能会坚持显示所有值的小数位。

于 2013-07-12T06:52:29.473 回答