Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MaterialTextField TextChanged infinite loop #88

Closed
thiagoparabas opened this issue Feb 28, 2019 · 3 comments
Closed

MaterialTextField TextChanged infinite loop #88

thiagoparabas opened this issue Feb 28, 2019 · 3 comments
Labels
bug Something isn't working valid This issue/bug/feature request is valid

Comments

@thiagoparabas
Copy link

When trying to directly change the text in the change, it goes into infinite loop.

private void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            var entry = sender as MaterialTextField;

            var text = entry?.Text;

            if (string.IsNullOrWhiteSpace(text) || _positions == null)
                return;

            if (text.Length > _mask.Length)
            {
                entry.Text = text.Remove(text.Length - 1);
                return;
            }

            foreach (var position in _positions)
                if (text.Length >= position.Key + 1)
                {
                    var value = position.Value.ToString();
                    if (text.Substring(position.Key, 1) != value)
                        text = text.Insert(position.Key, value);
                }

            if (entry.Text != text)
                entry.Text = text;
        }
@thiagoparabas thiagoparabas changed the title MaterialTextField TextChanged Infinity loop MaterialTextField TextChanged infinite loop Feb 28, 2019
@contrix09 contrix09 self-assigned this Mar 1, 2019
@contrix09 contrix09 added bug Something isn't working valid This issue/bug/feature request is valid labels Mar 1, 2019
@contrix09
Copy link

Hi. In what line does the looping occur. I tried to replicate the looping, and it happens when you set the Text property of the text field. Heres the code:

private void MaterialTextField_TextChanged(object sender, TextChangedEventArgs e)
{
    const int maxLength = 4;
    var entry = sender as MaterialTextField;

    var text = entry.Text ?? string.Empty;

    if(text.Length > maxLength)
    {
        entry.Text = entry.Text.Substring(0, maxLength);
    }
}

@contrix09
Copy link

After some investigation, the looping was caused by the TextChanged event of the text field. It fires when the Text property is about to change, not when it has changed.

Can you provide the other field declarations (_positions and _mask) from your code above so I can test it.

@thiagoparabas
Copy link
Author

Yes, sure, following:

This is my behavior

public class MaskedBehavior : Behavior<MaterialTextField>
{
    private string _mask = "";
    public string Mask
    {
        get => _mask;
        set
        {
            _mask = value;
            SetPositions();
        }
    }

    protected override void OnAttachedTo(MaterialTextField entry)
    {
        entry.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(entry);
    }

    protected override void OnDetachingFrom(MaterialTextField entry)
    {
         entry.TextChanged -= OnEntryTextChanged;
         base.OnDetachingFrom(entry);
    }

    IDictionary<int, char> _positions;

    void SetPositions()
    {
        if (string.IsNullOrEmpty(Mask))
        {
            _positions = null;
            return;
        }

        var list = new Dictionary<int, char>();
        for (var i = 0; i < Mask.Length; i++)
            if (Mask[i] != 'X')
                list.Add(i, Mask[i]);

        _positions = list;
    }

    private void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        var entry = sender as MaterialTextField;

        var text = entry.Text;

        if (string.IsNullOrWhiteSpace(text) || _positions == null)
            return;

        if (text.Length > _mask.Length)
        {
            entry.Text = text.Remove(text.Length - 1);
            return;
        }

        foreach (var position in _positions)
            if (text.Length >= position.Key + 1)
            {
                var value = position.Value.ToString();
                if (text.Substring(position.Key, 1) != value)
                    text = text.Insert(position.Key, value);
            }

        if (entry.Text != text)
            entry.Text = text;
    }
}

@contrix09 contrix09 removed their assignment Sep 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working valid This issue/bug/feature request is valid
Projects
None yet
Development

No branches or pull requests

1 participant