Как программно запустить событие TextChanged в поле ввода Xamarin Forms?

Мы настроили поведение Xamarin для ненулевых полей записи и т. Д., Это срабатывает, когда пользователь вносит изменения в поле, а затем мы изменили цвет границы записи, красный для недопустимого.

Однако мы также хотели бы повторно использовать это поведение при нажатии кнопки отправки.

Итак, мне нужно запустить событие TextChanged вручную, есть идеи, как я могу это сделать, теперь уверен, возможно ли это?

public class NotEmptyEntryBehaviour : Behavior<Entry>
{
    protected override void OnAttachedTo(Entry bindable)
    {
        bindable.TextChanged += OnEntryTextChanged;
        base.OnAttachedTo(bindable);
    }

    protected override void OnDetachingFrom(Entry bindable)
    {
        bindable.TextChanged -= OnEntryTextChanged;
        base.OnDetachingFrom(bindable);
    }

    void OnEntryTextChanged(object sender, TextChangedEventArgs args)
    {
        if (args == null)
            return;

        var oldString = args.OldTextValue;
        var newString = args.NewTextValue;
    }
}

person Jules    schedule 30.03.2021    source источник


Ответы (2)


Если вам нужна альтернатива, вы можете использовать одно из предварительно созданных поведений проверки, которое поставляется с Xamarin.CommunityToolkit package, например TextValidationBehavior (указав Regexp) или любые более конкретные производные (пример NumericValidationBehavior), которые могут соответствовать вашим потребностям, или даже создать собственный, создав подкласс ValidationBehavior.

Он позволяет вам определять собственные стили для состояний Valid и InValid, но более важным для вопроса является асинхронный метод под названием ForceValidate().

Также / a> свойство могло быть интересно.

NotEmptyEntryBehaviour кажется ближе к TextValidationBehavior с MinimumLenght=1

xaml

 <Entry Placeholder="Type something..." x:Name="entry">
        <Entry.Behaviors>
            <xct:TextValidationBehavior Flags="ValidateOnValueChanging"
                                        InvalidStyle="{StaticResource InvalidEntryStyle}"
                                        ValidStyle="{StaticResource ValidEntryStyle}"/>
        </Entry.Behaviors>
    </Entry>

Код

await (entry.Behaviors[0] as TextValidationBehavior)?.ForceValidate();

Документы

https://docs.microsoft.com/en-us/xamarin/community-toolkit/behaviors/charactersvalidationbehavior.

Образцы репо

https://github.com/xamarin/XamarinCommunityToolkit/tree/main/samples/XCT.Sample/Pages/Behaviors

person Cfun    schedule 30.03.2021

Мы настроили поведение Xamarin для ненулевых полей записи и т. Д., Это срабатывает, когда пользователь вносит изменения в поле, а затем мы изменили цвет границы записи, красный для недопустимого.

Вы можете создать настраиваемую запись с поведением для получения.

Первое, что я собираюсь сделать, это создать новый элемент управления, который наследуется от Entry и добавит три свойства: IsBorderErrorVisible, BorderErrorColor, ErrorText.

public class ExtendedEntry : Entry
{
    public static readonly BindableProperty IsBorderErrorVisibleProperty =
        BindableProperty.Create(nameof(IsBorderErrorVisible), typeof(bool), typeof(ExtendedEntry), false, BindingMode.TwoWay);

    public bool IsBorderErrorVisible
    {
        get { return (bool)GetValue(IsBorderErrorVisibleProperty); }
        set
        {
            SetValue(IsBorderErrorVisibleProperty, value);
        }
    }

    public static readonly BindableProperty BorderErrorColorProperty =
        BindableProperty.Create(nameof(BorderErrorColor), typeof(Xamarin.Forms.Color), typeof(ExtendedEntry), Xamarin.Forms.Color.Transparent, BindingMode.TwoWay);

    public Xamarin.Forms.Color BorderErrorColor
    {
        get { return (Xamarin.Forms.Color)GetValue(BorderErrorColorProperty); }
        set
        {
            SetValue(BorderErrorColorProperty, value);
        }
    }

    public static readonly BindableProperty ErrorTextProperty =
    BindableProperty.Create(nameof(ErrorText), typeof(string), typeof(ExtendedEntry), string.Empty);

    public string ErrorText
    {
        get { return (string)GetValue(ErrorTextProperty); }
        set
        {
            SetValue(ErrorTextProperty, value);
        }
    }
}

Затем создаем собственный рендер для платформы Android.

[assembly: ExportRenderer(typeof(ExtendedEntry), typeof(ExtendedEntryRenderer))]
namespace FormsSample.Droid
{
public class ExtendedEntryRenderer : EntryRenderer
{
    public ExtendedEntryRenderer(Context context) : base(context)
    {
    }
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        if (Control == null || e.NewElement == null) return;

        UpdateBorders();
    }

    protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (Control == null) return;

        if (e.PropertyName == ExtendedEntry.IsBorderErrorVisibleProperty.PropertyName)
            UpdateBorders();
    }

    void UpdateBorders()
    {
        GradientDrawable shape = new GradientDrawable();
        shape.SetShape(ShapeType.Rectangle);
        shape.SetCornerRadius(0);

        if (((ExtendedEntry)this.Element).IsBorderErrorVisible)
        {
            shape.SetStroke(3, ((ExtendedEntry)this.Element).BorderErrorColor.ToAndroid());
        }
        else
        {
            shape.SetStroke(3, Android.Graphics.Color.LightGray);
            this.Control.SetBackground(shape);
        }

        this.Control.SetBackground(shape);
    }

}

}

Наконец, создавая поведение входа, обработайте ошибку, чтобы предоставить пользователю обратную связь с пользовательским интерфейсом при проверке.

 public class EmptyEntryValidatorBehavior : Behavior<ExtendedEntry>
{
    ExtendedEntry control;
    string _placeHolder;
    Xamarin.Forms.Color _placeHolderColor;

    protected override void OnAttachedTo(ExtendedEntry bindable)
    {
        bindable.TextChanged += HandleTextChanged;
        bindable.PropertyChanged += OnPropertyChanged;
        control = bindable;
        _placeHolder = bindable.Placeholder;
        _placeHolderColor = bindable.PlaceholderColor;
    }

    void HandleTextChanged(object sender, TextChangedEventArgs e)
    {
        ExtendedEntry customentry = (ExtendedEntry)sender;
        if (!string.IsNullOrEmpty(customentry.Text))
        {
            ((ExtendedEntry)sender).IsBorderErrorVisible = false;
        }
        else
        {
            ((ExtendedEntry)sender).IsBorderErrorVisible = true;
        }
      
    }

    protected override void OnDetachingFrom(ExtendedEntry bindable)
    {
        bindable.TextChanged -= HandleTextChanged;
        bindable.PropertyChanged -= OnPropertyChanged;
    }

    void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == ExtendedEntry.IsBorderErrorVisibleProperty.PropertyName && control != null)
        {
            if (control.IsBorderErrorVisible)
            {
                control.Placeholder = control.ErrorText;
                control.PlaceholderColor = control.BorderErrorColor;
                control.Text = string.Empty;
            }

            else
            {
                control.Placeholder = _placeHolder;
                control.PlaceholderColor = _placeHolderColor;
            }

        }
    }
}

введите описание изображения здесь

Обновление:

Вы можете изменить IsBorderErrorVisible настраиваемой записи в button.click, чтобы вызвать это из кнопки отправки.

 private void btn1_Clicked(object sender, EventArgs e)
    {
       
        if(string.IsNullOrEmpty(entry1.Text))
        {
            entry1.IsBorderErrorVisible = true;
        }
    }

<customentry:ExtendedEntry
            x:Name="entry1"
            BorderErrorColor="Red"
            ErrorText="please enter name!">
            <customentry:ExtendedEntry.Behaviors>
                <behaviors:EmptyEntryValidatorBehavior />
            </customentry:ExtendedEntry.Behaviors>
        </customentry:ExtendedEntry>
person Cherry Bu - MSFT    schedule 31.03.2021
comment
Спасибо за это, но как мне вызвать это с помощью кнопки отправки, если они не коснулись полей ввода? - person Jules; 31.03.2021
comment
@Jules, пожалуйста, посмотрите мое обновление. - person Cherry Bu - MSFT; 31.03.2021
comment
Еще раз спасибо. После первоначального комментария по моему вопросу я абстрагировался от проверки и установил цвет границы для нового класса, по одному методу для каждой проверки. Затем у меня есть метод расширения IsValid, который перебирает все варианты поведения и выполняет мои проверки достоверности, которые я использую в своем представлении. Таким образом, мне не нужно знать, какая проверка, на мой взгляд, используется для контроля. Это лучшее решение, которое я здесь видел. Но я предпочитаю вызывать поведение, чем использовать методы проверки. - person Jules; 31.03.2021
comment
@Jules, спасибо, что поделился своим решением, мой ответ вам поможет? - person Cherry Bu - MSFT; 31.03.2021