Samet Sığırcı
Samet Sığırcı

Reputation: 97

Entry texts not align (- and numbers)

Im trying to build email code validator. Im sending 6 digit number to customer to enter his code on entry. But - and numbers has different width which cause when user enter the number then i replace - to number but it moving different alignment.I need to set them same line. How can i do it?

enter image description here

First one empty box, second one numbers and space, third one is how supposed to look.

Upvotes: 0

Views: 75

Answers (3)

ottermatic
ottermatic

Reputation: 1012

It would be helpful to see your code, but i'm going to take a stab at it. Use FormattedText and have each item (either - or number) as a span.

<Label InputTransparent="True">
    <Label.FormattedText>
        <FormattedString>
            <Span Text="{Binding Item1}" HorizontalOptions="Center" VerticalOptions="Center"/>
            <Span Text="{Binding Item2}" HorizontalOptions="Center" VerticalOptions="Center"/>
            <Span Text="{Binding Item3}" HorizontalOptions="Center" VerticalOptions="Center"/>
            <Span Text="{Binding Item4}" HorizontalOptions="Center" VerticalOptions="Center"/>
            <Span Text="{Binding Item5}" HorizontalOptions="Center" VerticalOptions="Center"/>
            <Span Text="{Binding Item6}" HorizontalOptions="Center" VerticalOptions="Center"/>
        </FormattedString>
    </Label.FormattedText>
</Label>

Layer that over an Entry with TextColor of Transparent. when the user inputs values simply set Item1 - Item6 to display as desired.

Upvotes: 0

Samet Sığırcı
Samet Sığırcı

Reputation: 97

I solved it with set HorizontalTextAlignment to center.

<Grid HorizontalOptions="CenterAndExpand" ColumnSpacing="0" WidthRequest="205">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="0"
                             Keyboard="Numeric" MaxLength="1" TextChanged="Entry_TextChanged"></Entry>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="1"
                             Keyboard="Numeric" MaxLength="1" TextChanged="Entry_TextChanged"></Entry>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="2"
                             Keyboard="Numeric" MaxLength="1" TextChanged="Entry_TextChanged"></Entry>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="3"
                             Keyboard="Numeric" MaxLength="1" TextChanged="Entry_TextChanged"></Entry>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="4"
                             Keyboard="Numeric" MaxLength="1" TextChanged="Entry_TextChanged"></Entry>
                        <Entry Placeholder="—" HorizontalOptions="Center" HorizontalTextAlignment="Center" Grid.Column="5"
                             Keyboard="Numeric" MaxLength="1"></Entry>
                    </Grid>

And add this C# code for when value entered focus on next entry.

    private void Entry_TextChanged(object sender, TextChangedEventArgs e)
    {
        var entry = sender as Entry;
        var list = (entry.Parent as Grid).Children;
        var index = list.IndexOf(entry);
        int nextIndex = 0;

        if (e.NewTextValue.Length > 0)
            nextIndex = (index + 1) >= list.Count ? 0 : index + 1;
        else if (e.NewTextValue.Length < 1 && index > 0)
            nextIndex = (index - 1);

        var next = list.ElementAt(nextIndex);
        next?.Focus();
    }

Upvotes: 0

Mihail Duchev
Mihail Duchev

Reputation: 4821

This is the perfect example of using Xamarin.Forms Grid layout

If you check out the Usage section, you will see what will happen if you decide to have proportional sizes:

Proportional() – sizes columns and rows as a proportion of the remaining space. Specified as a value and GridUnitType.Star in C# and as # in XAML, with # being your desired value. Specifying one row/column with * will cause it to fill the available space.

What this means is that if you want to have 6 equal columns, you can do it like so:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
</Grid>

This way, each column will be equal to the rest and will be exactly 1/6 of the size that the grid has occupied.

You can simply place your controls inside the grid, align them accordingly and you are good to go.

P.S. If you have some special symbols, or a mixture of numbers & letters, they still may not be perfectly aligned and you will have to use a font with Fixed-pitch

Upvotes: 1

Related Questions