Вопрос об обязательном владении Mask Behavior - PullRequest
0 голосов
/ 24 марта 2020

Я пытаюсь реализовать маску для адаптации ввода моего номера телефона, но я собираю поведение из страны, которую выбрал пользователь.

<Entry Keyboard="Numeric" Placeholder="Telephone Number" BackgroundColor="#FFFFFF" IsSpellCheckEnabled="True">
    <Entry.Behaviors>
        <behaviors:MaskedBehavior Mask="{Binding SelectedCountry.Mask}" />
    </Entry.Behaviors>
</Entry>

Но когда значение будет работать Поведение: что-то идет не так.

public class MaskedBehavior : Behavior<Entry>
{
    private string _mask = "(XXX) XXXX XXXX";

    public static readonly BindableProperty MaskProperty =
        BindableProperty.Create("Mask", typeof(string), typeof(MaskedBehavior), 
        null, BindingMode.TwoWay, null, propertyChanged: OnItemsSourceChanged);

    static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var control = (MaskedBehavior)bindable;
        control.Mask = (string)newValue;
    }

    public string Mask
    {
        get { return (string)GetValue(MaskProperty); }
        set 
        { 
            SetValue(MaskProperty, _mask);
            SetPositions();
        }
    }


    private void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        var entry = sender as Entry;
        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;
    }


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

    protected override void OnDetachingFrom(Entry 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;
    }

Список источников подобен этому, я просто что-то придумал, но после того, как собираюсь исправить его как правильное.

**Xaml**
<Picker HeightRequest ="40"
        WidthRequest="300"
        Title="Country/Region"
        ItemsSource="{Binding Countries}"
        ItemDisplayBinding="{Binding CountryName}"
        SelectedItem="{Binding SelectedCountry}"
**C#**
static CountriesData()
{
    Countries = new List<Country>();

    Countries.Add(new Country
    {
        Id = "93",
        CountryName = "Afghanistan (+93)",
        Mask = "(XXX) XXXX XXXX"
    });
    Countries.Add(new Country
    {
        Id = "335",
        CountryName = "Albania (+355)",
        Mask = "(XXX) XXXX XXX"
    });
}

Если кто-то может дать руку, пожалуйста =) Извините, это мой первый проект, если я не express мне правильный путь = /

1 Ответ

0 голосов
/ 25 марта 2020

Создайте BehaviorBase для обновления behavior.

public class BehaviorBase<T> : Behavior<T> where T : BindableObject
{
    #region Properties
    public T AssociatedObject
    {
        get;
        private set;
    }
    #endregion
    #region NormalMethods
    private void OnBindingContextChanged(object sender, EventArgs e)
    {
        OnBindingContextChanged();
    }
    #endregion
    #region Overrides
    protected override void OnAttachedTo(T bindable)
    {
        base.OnAttachedTo(bindable);
        AssociatedObject = bindable;
        if (bindable.BindingContext != null)
        {
            BindingContext = bindable.BindingContext;
        }

        bindable.BindingContextChanged += OnBindingContextChanged;
    }
    protected override void OnDetachingFrom(T bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.BindingContextChanged -= OnBindingContextChanged;
        AssociatedObject = null;
    }
    protected override void OnBindingContextChanged()
    {
        base.OnBindingContextChanged();
        BindingContext = AssociatedObject.BindingContext;
    }
    #endregion
}

Сделайте ваш MaskedBehavior наследовать BehaviorBase.

public class MaskedBehavior : BehaviorBase<Entry>
{
    ……..
 }

То же использование, что и у вас.

enter image description here

Я загрузил весь проект на GitHub, вы можете скачать его для справки. https://github.com/WendyZang/Test/tree/master/Behavior

...