【发布时间】:2019-06-03 17:23:24
【问题描述】:
有没有办法强制输入大写以及如何将选择器内的项目大写?如果可能不使用插件
【问题讨论】:
标签: xamarin xamarin.forms
有没有办法强制输入大写以及如何将选择器内的项目大写?如果可能不使用插件
【问题讨论】:
标签: xamarin xamarin.forms
如果您想在 Entry 中强制使用大写,有几种方法可以做到这一点,但这次我们使用 Effects。
如果您还没有听说过 Effects,您可以快速阅读它们的用途 here
首先,您需要在 Xamarin.Forms 项目中创建效果。
为简单起见,我将其称为EntryAllCapitalEffect,代码如下所示:
namespace YourAwesomeNamespace
{
public class EntryAllCapitalEffect : RoutingEffect
{
public EntryAllCapitalEffect() : base("StackOverflow.EntryAllCapitalEffect")
{
}
}
}
StackOverflow 是您的公司名称,EntryAllCapitalEffect 是效果名称。
现在我们需要在每个平台项目中实现效果。
让我们从 Android 开始:
让我们在 Android 项目中创建一个名为 EntryAllCapitalEffect 的文件,并将下面的代码添加为实现的一部分。
[assembly: ResolutionGroupName("StackOverflow")] //Remember your companyName ?
[assembly: ExportEffect(typeof(YourAwesomeNamespace.Droid.EntryAllCapitalEffect), "EntryAllCapitalEffect")]
namespace YourAwesomeNamespace.Droid
{
public class EntryAllCapitalEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
//Let's don't do anything if the control is not a EditText
if (!(Control is EditText editText))
{
return;
}
//Force the keyboard setup all Caps letters
// But the user can still change the Caps taping on Shift
editText.InputType = InputTypes.TextFlagCapCharacters;
// Update any lowercase into Uppercase
var filters = new List<IInputFilter>(editText.GetFilters());
filters.Add(new InputFilterAllCaps());
editText.SetFilters(filters.ToArray());
}
catch (Exception) { }
}
protected override void OnDetached()
{
}
}
}
现在让我们继续iOS
与 Android 相同,让我们在 iOS 项目中创建一个名为 EntryAllCapitalEffect 的文件。将以下代码添加到类中。
[assembly: ResolutionGroupName("StackOverflow")] // Again your CompanyName
[assembly: ExportEffect(typeof(YourAwesomeNamespace.iOS.EntryAllCapitalEffect), "EntryAllCapitalEffect")]
namespace YourAwesomeNamespace.iOS
{
public class EntryAllCapitalEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
if (!(Control is UITextField uiTextField))
{
return;
}
//Force the keyboard setup all Caps letters
// But the user can still change the Caps taping on Shift
uiTextField.AutocapitalizationType = UITextAutocapitalizationType.AllCharacters;
//Delegate to replace any Lowercase entry into UpperCase
uiTextField.ShouldChangeCharacters = OnShouldChangeCharacters;
}
catch (Exception) { }
}
protected override void OnDetached()
{
}
private bool OnShouldChangeCharacters(UITextField textfield, NSRange range, string replacementString)
{
using (NSString original = new NSString(textfield.Text), newString = new NSString(replacementString.ToUpper()))
{
textfield.Text = original.Replace(range, newString);
}
return false;
}
}
}
好的,现在使用它只需将其分配给 XAML 中的任何 Entry,如下所示:
<Entry HorizontalOptions="FillAndExpand" Placeholder="Enter Text here" >
<Entry.Effects>
<local:EntryAllCapitalEffect />
</Entry.Effects>
</Entry>
记得在 XAML 中添加本地别名
xmlns:local="clr-namespace:YourAwesomeNamespace"
这将是你的 Effect 所在的命名空间。
注意:您的 CompanyName 可以是任何东西,但它必须匹配所有放置此使用的位置。
注意2:如果您有其他Effects,则无需重复CompanyName注册。平台只执行一次。
希望这会有所帮助。-
【讨论】:
对于 Entry,您可以在 TextChanged 事件中将文本更改为大写。
对于 Picker,你通常控制 ItemsSource,你只需要将 ItemsSource 中的每个字符串都大写即可。
public MainPage()
{
InitializeComponent();
IList<Item> dummyData= new List<Item>
{
new Item { Id = 0, Name = "Item 0" },
new Item { Id = 1, Name = "Item 1" },
new Item { Id = 2, Name = "Item 2" },
};
picker.ItemsSource = dummyData
.Select(i => i.Name.ToUpperInvariant())
.ToList();
entry.TextChanged += OnTextChanged;
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
(sender as Entry).Text = e.NewTextValue.ToUpperInvariant();
}
如果您使用的是 MVVM,则可以使用 Entry.Text 和 Picker.ItemsSource 绑定的自定义转换器将值更改为大写。
【讨论】:
这是基于@Roger Leblanc 的回答的更多解决方案
创建一个行为:
public class AllCapsBehavior : Behavior<Entry>
{
protected override void OnAttachedTo(Entry entry)
{
entry.TextChanged += OnEntryTextChanged;
base.OnAttachedTo(entry);
}
protected override void OnDetachingFrom(Entry entry)
{
entry.TextChanged -= OnEntryTextChanged;
base.OnDetachingFrom(entry);
}
private static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
{
((Entry)sender).Text = args.NewTextValue.ToUpperInvariant();
}
}
将命名空间引用添加到视图:
xmlns:behav="clr-namespace:yourproject.Resources.Behaviors"
向条目添加行为:
<Entry>
<Entry.Behaviors>
<behav:AllCapsBehavior/>
</Entry.Behaviors>
</Entry>
【讨论】: