如何在Xamarin.Forms条目中仅允许数字?

时间:2019-03-06 01:39:00

标签: c# xaml xamarin xamarin.forms

我正在使用xamarin.forms条目制作各种类型的专用货币计算器。因为它是一个计算器,所以我只想允许数字,句点,逗号,以及美元符号(如果可能)。我是编程新手,因此尝试遵循here的行为示例,该行为可以部分完成这项工作。这段代码似乎比做一件看起来很简单并且甚至没有做我想做的事情的工作要复杂。我尝试了其他方法/方式,但它们是几年前的,似乎不再起作用。这是我到目前为止在C#中拥有的东西

using System;
using Xamarin.Forms;

namespace CattleCalc
{
    class BehaviorsPage
    {
        public class NumbersOnlyBehavior : Behavior<Entry>
            {


            protected Action<Entry, string> AdditionalCheck;

            protected override void OnAttachedTo(Entry bindable)
            {
                base.OnAttachedTo(bindable);

                bindable.TextChanged += TextChanged_Handler;
            }

            protected override void OnDetachingFrom(Entry bindable)
            {
                base.OnDetachingFrom(bindable);
            }

            protected virtual void TextChanged_Handler(object sender, TextChangedEventArgs e)
            {
                if (string.IsNullOrEmpty(e.NewTextValue))
                {
                    ((Entry)sender).Text = 0.ToString();
                    return;
                }

                double _;
                if (!double.TryParse(e.NewTextValue, out _))
                    ((Entry)sender).Text = e.OldTextValue;
                else
                    AdditionalCheck?.Invoke(((Entry)sender), e.OldTextValue);
            }
        }
    }
}

还有MainPage.Xaml中的一个条目示例...

        <customentry:MyEntry x:Name="PurchasePriceEntry" Text="{Binding Source={x:Reference PurchasePriceStepper}, Path=Value}" Placeholder="1.60" 
                             TextColor="DarkSlateGray" FontAttributes="Bold" BackgroundColor="Ivory" TranslationX="3"
                             Grid.Column="1" Grid.Row="0" HorizontalTextAlignment="Center" Keyboard="Numeric" ReturnType="Next" VerticalOptions="End" MaxLength="5"
                             TextChanged="PurchasePriceEntry_Completed">
            <Entry.Behaviors>
                <local:NumbersOnlyBehavior />
            </Entry.Behaviors>            
        </customentry:MyEntry>

运行此命令时,我得到了一些错误,基本上表明未发现我的行为。还是有一种更简单的方法?我根本不反对废弃此代码,而要比使用行为更容易/更简单,那就走另一条路!

1 个答案:

答案 0 :(得分:1)

是的,您的方向正确,除了自定义渲染器或添加的行为之外,没有其他简便的方法

您最可能丢失的是适当的xmlns XAML Namespace Declaration

xmlns:behavior="clr-namespace:<yourNameSpave>;assembly=<YourAssembly"

完整示例

<Page x:Class="WPFApplication1.MainPage"  
    ...
    xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary">  
  ...  
  <custom:ExampleClass/>  
...  
</Page>

作为一个旁注,我创建了一个我经常使用的用于处理负数和空白的函数,这可能也很有用。

public class NumericValidationBehavior : 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)
   {
      if (string.IsNullOrWhiteSpace(args.NewTextValue))
      {
         ((Entry)sender).Text = "0";
         return;
      }

      var isValid = args.NewTextValue.ToCharArray()
                        .All(char.IsDigit) || (args.NewTextValue.Length > 1 &&  args.NewTextValue.StartsWith("-") ); //Make sure all characters are numbers

      var current = args.NewTextValue;
      current = current.TrimStart('0');

      if (current.Length == 0)
      {
         current = "0";
      }

      ((Entry)sender).Text = isValid ? current : current.Remove(current.Length - 1);
   }
}