C# 如何以编程方式在Xamarin表单输入字段上触发TextChanged事件?
我们已经为非空输入字段等设置了一些Xamarin行为,当用户对字段进行更改,然后我们更改了输入边框颜色,红色表示无效时,将触发该行为 但是,当点击提交按钮时,我们也希望重用这种行为 所以我需要手动触发C# 如何以编程方式在Xamarin表单输入字段上触发TextChanged事件?,c#,xamarin,xamarin.forms,attachedbehaviors,C#,Xamarin,Xamarin.forms,Attachedbehaviors,我们已经为非空输入字段等设置了一些Xamarin行为,当用户对字段进行更改,然后我们更改了输入边框颜色,红色表示无效时,将触发该行为 但是,当点击提交按钮时,我们也希望重用这种行为 所以我需要手动触发TextChanged事件,有什么办法吗,现在确定是否可行 public class NotEmptyEntryBehaviour : Behavior<Entry> { protected override void OnAttachedTo(Entry bindable)
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;
}
}
public类NotEmptyEntryBehaviour:行为
{
受保护的覆盖无效数据到(条目可绑定)
{
bindable.TextChanged+=OnEntryTextChanged;
碱。可粘合的DTO(可粘合);
}
受保护的覆盖无效OnDetachingFrom(条目可绑定)
{
bindable.TextChanged-=OnEntryTextChanged;
基础。从(可装订)开始连接;
}
void OnEntryTextChanged(对象发送方,textchangedventargs args)
{
如果(args==null)
返回;
var oldString=args.OldTextValue;
var newString=args.NewTextValue;
}
}
如果您想要一个替代方案,您可以使用随附的预构建验证行为之一,如TextValidationBehavior
(通过指定Regexp)或任何更具体的派生行为(例如NumericValidationBehavior
),这些行为可能适合您的需要,甚至可以通过细分创建自定义行为
它允许您为有效和无效状态定义自定义样式,但更重要的是,它有一个名为ForceValidate()
的异步方法
此外,该物业可能会很有趣
NotEmptyEntryBehaviour
似乎更接近TextValidationBehavior
的最小长度=1
xaml
<Entry Placeholder="Type something..." x:Name="entry">
<Entry.Behaviors>
<xct:TextValidationBehavior Flags="ValidateOnValueChanging"
InvalidStyle="{StaticResource InvalidEntryStyle}"
ValidStyle="{StaticResource ValidEntryStyle}"/>
</Entry.Behaviors>
</Entry>
文件
回购样本
我们已经为非空输入字段等设置了一些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);
}
}
[程序集:ExportRenderer(typeof(ExtendedEntry)、typeof(ExtendedEntryRenderer))]
命名空间FormsSample.Droid
{
公共类ExtendedEntryRenderer:EntryRenderer
{
公共ExtendedEntryRenderer(上下文):基本(上下文)
{
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(Control==null | | e.NewElement==null)返回;
updateOrders();
}
受保护的覆盖无效OneElementPropertyChanged(对象发送方,System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(发送方,e);
if(Control==null)返回;
if(e.PropertyName==ExtendedEntry.IsBorderErrorVisibleProperty.PropertyName)
updateOrders();
}
void updateOrders()
{
GradientDrawable形状=新的GradientDrawable();
shape.SetShape(ShapeType.Rectangle);
形状。设置角半径(0);
if(((ExtendedEntry)this.Element).IsBorderErrorVisible)
{
shape.SetStroke(3,((ExtendedEntry)this.Element.BorderErrorColor.ToAndroid());
}
其他的
{
形状。设定行程(3,安卓。图形。颜色。浅灰色);
本.对照.立根(形状);
}
本.对照.立根(形状);
}
}
}
最后,创建一个条目行为,处理错误以在验证发生时向用户提供ui反馈
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;
}
}
}
}
公共类EmptyEntryValidatorBehavior:行为
{
扩展进入控制;
字符串占位符;
Xamarin.Forms.Color\u占位符颜色;
受保护的覆盖无效的附加到(ExtendedEntry可绑定)
{
bindable.TextChanged+=HandleTextChanged;
bindable.PropertyChanged+=OnPropertyChanged;
控件=可绑定;
_占位符=可绑定。占位符;
_占位符颜色=bindable.placeholder颜色;
}
void HandleTextChanged(对象发送者,textchangedventargs e)
{
ExtendedEntry customentry=(ExtendedEntry)发件人;
如果(!string.IsNullOrEmpty(customentry.Text))
{
((ExtendedEntry)发件人).IsBorderErrorVisible=false;
}
其他的
{
((ExtendedEntry)sender).IsBorderErrorVisible=true;
}
}
受保护的覆盖无效OnDetachingFrom(ExtendedEntry可绑定)
{
bindable.TextChanged-=HandleTextChanged;
bindable.PropertyChanged-=OnPropertyChanged;
}
void OnPropertyChanged(对象发送方,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;
}
其他的
{
control.Placeholder=\u占位符;
control.PlaceholderColor=\u PlaceholderColor;
}
}
}
}
更新:
您可以更改自定义条目的IsBorderErrorVisible in按钮。单击,可从提交按钮调用此按钮
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>
private void btn1\u已单击(对象发送方,事件参数e)
{
if(string.IsNullOrEmpty(entry1.Text))
{
entry1.IsBorderErrorVisible=true;
}
}
谢谢,但是如果他们没有触及输入字段,我该如何从提交按钮调用它?@Jules请查看我的更新。再次感谢,在我的q上的初始评论之后
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>