使用ShouldChangeCharacters打破mvvmcross数据绑定

时间:2014-03-28 00:34:24

标签: ios data-binding mvvmcross

我将UITextField子类化为电话号码输入,我为ShouldChangeCharacters添加了一个委托,以确保输入采用ddd-ddd-dddd格式。我自动插入破折号并处理退格以包含破折号。

我直接修改了字段文本,并始终从委托中返回false。

        this.ShouldChangeCharacters = (field, range, replacementString) =>
        {
            int oldLength = field.Text.Length;
            int replacementLength = replacementString.Length;
            int rangeLength = range.Length;
            int newLength = oldLength - rangeLength + replacementLength;
            if (newLength <= 12)
            {
                if (replacementLength == 0)
                {
                    if (field.Text.EndsWith("-"))
                        field.Text = field.Text.Substring(0, field.Text.Length - 2);
                    else
                        field.Text = field.Text.Substring(0, field.Text.Length - 1);

                }
                else
                {
                    int digit = 0;
                    if (int.TryParse(replacementString, out digit))
                    {
                        field.Text = field.Text + replacementString;
                        if (newLength == 3 || newLength == 7)
                            field.Text = field.Text + "-";
                    }
                }
            }
            return false;
        };

我遇到的问题是这似乎绕过了mvvmcross数据绑定。在我的绑定集中(在视图中)我使用了:

set.Bind(textPhone).To(vm => vm.Phone);

我的视图模型中未设置Phone属性。

无论如何都要确保数据绑定能够看到对UITextField Text属性的更改吗?

2 个答案:

答案 0 :(得分:0)

这里的问题(我认为)是返回false会阻止EditingChanged事件被触发。

要解决这个问题,最简单的方法是添加一个新的UITextField控件:

    public class MyField : UITextField
    {
        public MyField (RectangleF rect)
            : base(rect)
        {
            this.ShouldChangeCharacters = (f, r, r2) => {

                                    // your logic here
                this.Text += ".";

                                    var handler = CleanTextChanged;
                if (handler != null)
                    handler(this, EventArgs.Empty);
                return false;
            };                          
        }

        public event EventHandler CleanTextChanged;

        public string CleanText { 
            get { return Text; }
            set { Text = value; }
        }
    }

然后可以使用它来代替UITextField,并且可以使用以下命令绑定:

set.Bind(cleanTextPhone).For(v => v.CleanText).To(vm => vm.Phone);

如果您想使用较小的表达式 - 没有For - 那么您需要添加CleanText作为MyField

的默认绑定属性

答案 1 :(得分:0)

一种更简单的方法是在设置文字后执行以下操作

IBarConsumerFactory

相信这个答案: https://stackoverflow.com/a/35792058/5137291