18

I've got two labels next to each other. The first is pretty long and should get truncated if necessary. The second should be displayed completely - no matter what.

This is my code:

MainPage = new ContentPage {
    Content = new StackLayout {
        Orientation = StackOrientation.Horizontal,
        VerticalOptions = LayoutOptions.CenterAndExpand,
        BackgroundColor = Color.Orange,
        Padding = 10,
        Children = {
            new Label {
                Text = "The answer to life the universe and everything",
                HorizontalOptions = LayoutOptions.Start,
                LineBreakMode = LineBreakMode.TailTruncation,
                BackgroundColor = Color.Yellow,
            },
            new Label {
                Text = "42",
                HorizontalOptions = LayoutOptions.EndAndExpand,
                LineBreakMode = LineBreakMode.NoWrap,
                BackgroundColor = Color.Yellow,
            },
        },
    },
};

This is what I get:

My question: How can I prevent "42" from getting cut off?

Explanation of the current result: I think I know, why the second label is too small. The size of both labels is negotiated before the first text is truncated. So both labels need to shrink a bit, although the first label could handle it better.

Idea 1: I experimented with a relative layout (instead of the stack layout). However, it's a rather complicated approach and I get different results on iOS and Android. So I hope for a simpler fix.

Idea 2: Should I override one of the layouting or size negotiation methods? Maybe the "42" layout can enforce getting it's desired width.

Idea 3: Maybe we can come up with custom label renderers for iOS and Android that handle the size negotiation as expected.


Update

"42" is just an example. In my final app, this will change dynamically and can be a string of different length. So setting MinimumWidthRequest doesn't help without knowing the width of the rendered string.

Falko
  • 17,076
  • 13
  • 60
  • 105

3 Answers3

13

How can I prevent "42" from getting cut off?

You can set the MinimumWidthRequest in the "42" Label to prevent it from being cut off.

For details about MinimumWidthRequest please refer to remarks section of the document.

Code example:

MainPage = new ContentPage {
    Content = new StackLayout {
        Orientation = StackOrientation.Horizontal,
        VerticalOptions = LayoutOptions.CenterAndExpand,
        BackgroundColor = Color.Orange,
        Padding = 10,
        Children = {
           new Label {
              Text = "The answer to life the universe and everything The answer to life the universe and everything",
              HorizontalOptions = LayoutOptions.Start,
              LineBreakMode = LineBreakMode.TailTruncation,
              BackgroundColor = Color.Yellow,
           },
           new Label {
              MinimumWidthRequest = 50,
              Text = "42",
              HorizontalOptions = LayoutOptions.EndAndExpand,
              LineBreakMode = LineBreakMode.NoWrap,
              BackgroundColor = Color.Yellow,
           },
       },
    },
};

Here is the result:

enter image description here

Falko
  • 17,076
  • 13
  • 60
  • 105
Mike Ma
  • 2,017
  • 1
  • 12
  • 17
  • Thanks, Mike! I am, however, aware of the `MinimumWidthRequest` property. Sorry for not making it clear in my question, but "42" is just a very simple example and will be a dynamic value of different length in my app. I'll update my question accordingly. – Falko Jan 26 '17 at 08:29
  • 3
    @Falko just keep the `MinimumWidthRequest` bigger than your label width size ,setting the `MinimumWidthRequest` big enough like 500.Or customer the label set the `MinimumWidthRequest` bigger than your label width size I not familiar with ios. But in android side you can get the size in `OnMeasure` function. I think ios should be similar. – Mike Ma Jan 26 '17 at 08:34
  • 9
    WOW! This. Is. Just. Awesome! And it's absolutely counterintuitive that a *minimum* width request of an arbitrarily large number scales the label just right. The yellow box doesn't even get larger than it's text "42" if the left text is shorter and not truncated. I thought your value of 50 is fine-tuned to this example. But I'll simply use a large constant like 1000 or 1e6 and it perfectly works on Android and iOS. – Falko Jan 26 '17 at 17:00
3

Here you can use Grid instead of StackLayout. This will solve your problem.

Grid:

var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
Falko
  • 17,076
  • 13
  • 60
  • 105
  • 1
    Thanks for your answer. Replacing the StackLayout with a Grid, however, is rather complicated and - depending on the surrounding app architecture not easily doable. It's similar to my Idea 1 and will probably introduce new difficulties. – Falko Jan 26 '17 at 17:03
1

Just try Label's "MaxLines" property to set line wise limits, in Xamarin.Forms 3.4 or above. Also, it's a bindable property

anandd360
  • 298
  • 3
  • 14