Monday, June 18, 2018

HorizontalTextAlignment is ignored after navigation

Leave a Comment

I have created a simple app, where users can see more information in section, if they tab a Label, which is seen on the pictures below.

The text is hidden

The text is shown

The problem is, that after navigating to AnotherPage and back, the text moves to left, even though I have set the HorizontalTextAlignment to End.
This only happens, when I have shown the section and hiding it again (by tapping on the Label twice). The problem is illustrated on the picture below, where y is located at the left side.

After navigation

My source code for showing a simple app with this problem, can be downloaded from this Dropbox link.

EDIT Added code example

The ContentPage is as simple as

<StackLayout>    <Grid>       <Grid.ColumnDefinitions>          <ColumnDefinition Width="*" />       </Grid.ColumnDefinitions>       <Label Text="Test" VerticalOptions="Start" />       <Label Text="{Binding Text}" HorizontalTextAlignment="End" TextColor="Red" HorizontalOptions="FillAndExpand" BackgroundColor="Yellow">          <Label.GestureRecognizers>             <TapGestureRecognizer Command="{Binding ChangeVisibilityCommand}" />          </Label.GestureRecognizers>       </Label>    </Grid>     <StackLayout IsVisible="{Binding IsVisible}">       <Label Text="Text 1" />       <Label Text="Text 2" />    </StackLayout>     <Button Command="{Binding OpenAnotherPageCommand}" Text="Open Another Page" />  </StackLayout> 

And the ViewModel is shown below

public class MainPageViewModel : INotifyPropertyChanged {    public event PropertyChangedEventHandler PropertyChanged;     private ICommand _changeVisibilityCommand;    public ICommand ChangeVisibilityCommand    {       get => _changeVisibilityCommand;       set       {          if (value != _changeVisibilityCommand)          {             _changeVisibilityCommand = value;             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ChangeVisibilityCommand)));          }       }    }     private bool _isVisible;    public bool IsVisible    {       get => _isVisible;       set       {          if (value != _isVisible)          {             _isVisible = value;             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsVisible)));          }       }    }     private ICommand _openAnotherPageCommand;    public ICommand OpenAnotherPageCommand    {       get => _openAnotherPageCommand;       set       {          if (value != _openAnotherPageCommand)          {             _openAnotherPageCommand = value;             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OpenAnotherPageCommand)));          }       }    }     private string _text = "u";    public string Text    {       get => _text;       set       {          if (!string.Equals(_text, value, StringComparison.InvariantCultureIgnoreCase))          {             _text = value;             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));          }       }    }     public MainPageViewModel()    {       ChangeVisibilityCommand = new Command(() =>       {          IsVisible = !IsVisible;          Text = IsVisible ? "x" : "y";       });        OpenAnotherPageCommand = new Command(() =>       {          (Application.Current.MainPage as NavigationPage)?.PushAsync(new AnotherPage());       });    } } 

And the AnotherPage is simply showing a text for example

2 Answers

Answers 1

First of all, i wasn't able to reproduce your issue using the latest version of Xamarin. Maybe simply upgrading Xamarin (Forms) will remove the unwanted behavior in your case as well.

If not, you have two options:

1 - Use HorizontalOptions instead

HorizontalOptions="EndAndExpand"

since HorizontalOptions has a higher priority in the layout engine. Not the most elegant way but surely the most reliable.

2 - Use DataBinding

In your model just add the following property:

    public TextAlignment LabelAlignment     {         get => labelAlignment;         set         {             labelAlignment = value;             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LabelAlignment)));         }     }     private TextAlignment labelAlignment = TextAlignment.End; 

And in your Xaml you change HorizontalAlignment to

HorizontalTextAlignment="{Binding LabelAlignment}"

That will work because after your screen has been created, the values in the model will be loaded and updated afterwards.

Answers 2

Change HorizontalOptions="FillAndExpand"

To HorizontalOptions="CenterAndExpand"

This will force the text to expand from the center and be placed at the end.

To force the text to the right, you can add a another column definition to your grid:

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

Place and emtpy object into the first cell, the one to the left:

  • number from the top (0)
  • number from the left (0)

and your label into the second cell, the one to the right:

  • number from the top (0)
  • number from the left (1)

The text area will adjust to the text length and will always be to the right.

I hope this information helps!

You can read more about grid in the documentation: https://docs.microsoft.com/en-us/xamarin/android/user-interface/layouts/grid-layout

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment