【问题标题】:How to upper case entry and picker in xamarin forms?如何在 xamarin 表单中大写输入和选择器?
【发布时间】:2019-06-03 17:23:24
【问题描述】:

有没有办法强制输入大写以及如何将选择器内的项目大写?如果可能不使用插件

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    如果您想在 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注册。平台只执行一次。

    希望这会有所帮助。-

    【讨论】:

      【解决方案2】:

      对于 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 绑定的自定义转换器将值更改为大写。

      【讨论】:

        【解决方案3】:

        这是基于@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>
        

        【讨论】:

          猜你喜欢
          • 2019-04-11
          • 2017-04-02
          • 2023-03-10
          • 1970-01-01
          • 2018-02-02
          • 2018-02-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-04
          相关资源
          最近更新 更多