【问题标题】:MVVMCross Binding decimal to UITextField removes decimal pointMVVMCross 绑定小数到 UITextField 删除小数点
【发布时间】:2013-07-11 21:21:29
【问题描述】:

将小数绑定到 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 绑定覆盖的语法/位置是什么?
  • 如何使用绑定语法为文本指定不同的绑定?

提前致谢。

【问题讨论】:

    标签: mvvm xamarin.ios xamarin mvvmcross


    【解决方案1】:

    用我的默认 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 中提供了有关初始化/设置顺序的更多信息(正在进行中)。

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

    行:

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

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

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

    1 个子类UITextField 提供不动产

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

    UITextField 子类化的示例显示在the N=33 video

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

    【讨论】:

    • 最后一件事 - 对于您的特定问题/挑战,我认为 MvvmCross 会对修复/建议感兴趣,如果您能想到任何...(尽管首先我也会抽出一些时间来为此设置一个测试工具 - 不是我以前在例如tipcalc中看到的)
    • 我创建了一个存储库来展示一些处理问题的方法:github.com/brianchance/MonoTouchMVVMCrossValidationTester,如果不清楚,请告诉我。在这次练习中学到了很多关于 MVVMCross 的知识。
    • 我能想到的一些建议是允许将选项从绑定语法传递给活页夹(例如Changing vs EndEdit),这样它们就可以更加灵活。像 set.Bind(field).Options(new {EndEdit = true}).To(vm => vm.SomeField); 之类的东西,另一个建议是使用信使发布转换错误或挂钩事件,以便可以给出反馈.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 2020-03-05
    相关资源
    最近更新 更多