C# 在用户键入类似于wpf中的PreviewKeyDown的内容时修改条目的文本属性
我希望在用户键入时有条件地过滤/更改C# 在用户键入类似于wpf中的PreviewKeyDown的内容时修改条目的文本属性,c#,xaml,xamarin,events,xamarin.forms,C#,Xaml,Xamarin,Events,Xamarin.forms,我希望在用户键入时有条件地过滤/更改条目的文本属性。事件在wpf中的方式与此相同:在KeyDown事件之前激发,该事件提供了在显示给用户之前修改用户输入的控制,而后者正在键入 不幸的是,在Xamarin,这样的事件并不存在。下面是我到目前为止尝试过的一个示例(将所有内容放在代码中仅用于示例),但导致堆栈溢出(在setter中的Entry\u TextChanged事件和notifypropertychanged之间反弹) 我的问题不是纠正我的代码,而是以一种干净的方式实现上面描述的需求 附言:
条目的文本
属性。事件在wpf中的方式与此相同:在KeyDown
事件之前激发,该事件提供了在显示给用户之前修改用户输入的控制,而后者正在键入
不幸的是,在Xamarin,这样的事件并不存在。下面是我到目前为止尝试过的一个示例(将所有内容放在代码中仅用于示例),但导致堆栈溢出(在setter中的Entry\u TextChanged
事件和notifypropertychanged
之间反弹)
我的问题不是纠正我的代码,而是以一种干净的方式实现上面描述的需求
附言:
在setter上执行条件修改不是一个选项,因为它不是一个好的设计,并且不可重用
MyPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:AppTest"
x:Class="AppTest.MainPage">
<StackLayout>
<Entry Text="{Binding entrystr}"
Keyboard="Numeric"
TextChanged="Entry_TextChanged"/>
</StackLayout>
</ContentPage>
我真的不喜欢在setter中进行设计,但似乎没有太多的选项,我试图使其更灵活/可重用
ViewModelBase.cs
public abstract class ViewModelBase: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void SetProperty<T>(ref T field, T value, Func<T, T, T> PrefilterMethod = null, [CallerMemberName] string name = null)
{
if (!Equals(field, value))
{
if (PrefilterMethod != null)
field = PrefilterMethod.Invoke(field, value);
else
field = value;
OnPropertyChanged(name);
}
}
protected void OnPropertyChanged([CallerMemberName] string name = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
MainPage.cs
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageViewModel();
}
当然,不再需要TextChanged
事件。Xamarin中没有这样的生命周期事件。在您的情况下,在Setter中处理逻辑似乎是最好(或唯一)的方法。使用自定义渲染器对您来说是可行的选择吗?就我个人而言,我会截取其中的输入,然后传递到表单,在那里用我想要的任何自定义过滤器进行处理,然后传递回渲染器。你可以自由回答,我不太熟悉自定义渲染,而且这可能对其他人有帮助。
public class MainPageViewModel : ViewModelBase
{
private string _EntryStr;
public string EntryStr
{
get => _EntryStr;
set => SetProperty(ref _EntryStr, value, Setter_Filter);
}
private string Setter_Filter(string oldstr, string newstr)
{
float OldValueFloat, NewValueFloat;
float.TryParse(oldstr, out OldValueFloat);
float.TryParse(newstr, out NewValueFloat);
return NewValueFloat > 5 ?
OldValueFloat.ToString() : NewValueFloat.ToString();
}
public MainPage()
{
InitializeComponent();
BindingContext = new MainPageViewModel();
}