How to get screen readers to read a number in an Entry as a decimal number rather than an incomplete sequence of digits and numbers?

John Hardman 161 Reputation points
2020-11-24T16:38:43.133+00:00

I have a Xamarin.Forms.Entry that is used for entering values.

I am now trying to improve how screen readers read the value in this Entry.

Currently, using XF 4.8, on devices set up for British English the following value
1500005.40

results in the following variations:

Windows Narrator: "One million, five hundred thousand and five point four zero"
VoiceOver on iOS: "One five zero zero zero zero five forty"
TalkBack on Android: "One million, five hundred thousand and five point four oh"

Of these, for British English, I prefer the Narrator output (which some might consider to be American English, but which is perfectly valid in British English). I can cope with the TalkBack version (although the use of oh as a number always makes me cringe). The VoiceOver version though is just user-unfriendly.

I could write a ValueConverter that goes through the long-winded process of constructing the spoken output that I want as a string, but I'm hoping there's a better way. Is there an iOS-specific trait that I can attach to the native view used for that Entry? Or is there another approach that doesn't require me to build the string up myself? I'm hoping that there is something in the o/s or .Net libraries that can do it for me, rather than me re-invent the wheel. Particularly, when localisation is taken into account, it would obviously be far better to rely on the o/s or .Net than to have to build variations of this for each variation.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,296 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. John Hardman 161 Reputation points
    2020-11-24T18:17:44.753+00:00

    I'm not sure this is the best way to do it (I would prefer to use a trait if an appropriate one exists), but a simple ValueConverter does seem to do the job. No need to manually build up the string, just use ToString to format it for the locale. Note that I haven't tested this for other locales yet.

    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        string inputValue = (string)value;
        decimal result;
        string finalResult 
            = decimal.TryParse(
                inputValue, 
                NumberStyles.Number | NumberStyles.AllowThousands | NumberStyles.AllowDecimalPoint | NumberStyles.AllowCurrencySymbol, 
                culture, 
                out result) 
                    ? result.ToString("N", culture) 
                    : inputValue;
        return finalResult;
    }