Stacklayout Label Widthrequest not working properly?

Hi everybody,

I really have troubles with formatting lists with custom CellViews properly. Let's assume I want to have a List with two columns (everyone is a label, basically) and the first label should have the same with in every row - as we all know this from tables ;-)
So I tried to use a "WidthRequest=100" on the first label.

This is the whole simple code for the layout

    public ProjectViewCell(){

        var lblProjectNumber = new Label{ HorizontalOptions = LayoutOptions.Start, WidthRequest = 100 , BackgroundColor=Color.Blue};
        var lblProjectName = new Label{ HorizontalOptions = LayoutOptions.Fill, LineBreakMode=LineBreakMode.TailTruncation };

        lblProjectNumber.SetBinding (Label.TextProperty, "ProjectNumber");
        lblProjectName.SetBinding (Label.TextProperty, "ProjectName");

        this.View = new StackLayout () {
            Orientation=StackOrientation.Horizontal,
            Children = {
                lblProjectNumber,
                lblProjectName
            }
        };
    }

But this results in NOT equally sized labels over all rows. (see attached screenshot). The length of the second text (right label) seems to have an impact on the size of the first label.

Any Ideas how I get this done without setting the width request of the second label too? I would not like to do that because then my app only looks nice in one special resolution.

Thank you!

Posts

  • ChaseFlorellChaseFlorell CAInsider, University mod

    well, I ran your code exactly as you have it, and it got your described behavior. There are other ways to accomplish what you're trying including using a Grid, but I wonder (as a first step), have you updated your version of Xamarin.Forms?

    > Get-Project -All | Update-Package Xamarin.Forms
    

    Here's the code I tested with.

    using System.Collections.Generic;
    using Xamarin.Forms;
    
    namespace ListViewCase
    {
        public class App
        {
            public static Page GetMainPage()
            {
                return new MyContentPage();
            }
        }
    
        public class MyContentPage : ContentPage
        {
            public MyContentPage()
            {
                var itemTemplate = new DataTemplate(typeof(MainMenuListItemTemplate));
                itemTemplate.CreateContent();
    
                var menuItems = new List<KeyValuePair<string, string>>
                {
                    new KeyValuePair<string, string>("one", "description of one"),
                    new KeyValuePair<string, string>("two two", "description of two"),
                    new KeyValuePair<string, string>("three", "description of three"),
                    new KeyValuePair<string, string>("4", "description of four"),
                    new KeyValuePair<string, string>("fivers", "description of five"),
                    new KeyValuePair<string, string>("six", "description of six"),
                    new KeyValuePair<string, string>("oceans seven", "description of seven")
                };
    
                Content = new ListView
                {
                    HorizontalOptions = LayoutOptions.Fill,
                    ItemTemplate = itemTemplate,
                    ItemsSource = menuItems
                };
            }
        }
    
        public class MainMenuListItemTemplate : ViewCell
        {
            public MainMenuListItemTemplate()
            {
                var lblProjectNumber = new Label { HorizontalOptions = LayoutOptions.Start, WidthRequest = 100, BackgroundColor = Color.Blue };
                var lblProjectName = new Label { HorizontalOptions = LayoutOptions.Fill, LineBreakMode = LineBreakMode.TailTruncation };
    
                lblProjectNumber.SetBinding(Label.TextProperty, "Key");
                lblProjectName.SetBinding(Label.TextProperty, "Value");
    
                View = new StackLayout
                {
                    Orientation = StackOrientation.Horizontal,
                    Children = {
                    lblProjectNumber,
                    lblProjectName
                }
                };
            }
        }
    }
    
  • ChaseFlorellChaseFlorell CAInsider, University mod

    here's the screenshot

  • RonaldKasperRonaldKasper ATMember ✭✭

    Hello Chase!
    Thank you for your reply. Well I think the problem only occurs, when the second label contains very short and very long text (as in my example)

    Lets say

    ONE Description of one

    TWO Description of two with a large text, which is maybe so long that you can't read it entirely in the cell

  • ChaseFlorellChaseFlorell CAInsider, University mod
    edited August 2014

    Try this and see how it goes. Unfortunately I don't know the performance implications of having a bunch of grids in a list. You'll just have to test and see.

            var lblProjectNumber = new Label { HorizontalOptions = LayoutOptions.Start, WidthRequest = 100, BackgroundColor = Color.Blue };
            lblProjectNumber.SetBinding(Label.TextProperty, "ProjectNumber");
    
            var lblProjectName = new Label { HorizontalOptions = LayoutOptions.Fill, LineBreakMode = LineBreakMode.TailTruncation };
            lblProjectName.SetBinding(Label.TextProperty, "ProjectName");
    
            var grid = new Grid
            {
                HorizontalOptions = LayoutOptions.Fill,
                RowSpacing = 0,
                ColumnSpacing = 0,
                Padding = new Thickness(0, 0, 0, 4),
                ColumnDefinitions = new ColumnDefinitionCollection
                {
                    new ColumnDefinition {Width = new GridLength(100, GridUnitType.Absolute)},
                    new ColumnDefinition {Width = new GridLength(2, GridUnitType.Auto)}
                }
            };
    
            grid.Children.Add(lblProjectNumber, 0, 0);
            grid.Children.Add(lblProjectName, 1, 0);
    
            View = grid;
    
  • RonaldKasperRonaldKasper ATMember ✭✭

    Yes! This is it. Thank you very much!

  • PaulDivanPaulDivan USMember ✭✭

    So maybe this insight will help. In developing a forms application I have found that you have the screen size in pixels but more importantly in what you might call "form" units. In android you get the form units by dividing the size in pixels by the density of the screen. On IOS boundary comes in form units and you get the pixels by multiplying them by the scale:

    Android example (I store the values in a static SupportFunctions class in both cases:

                //
                // Get the screen size
                //
                Android.Util.DisplayMetrics metrics = Resources.DisplayMetrics;
                SupportFunctions.ScreenWidthPixels = metrics.WidthPixels;
                SupportFunctions.ScreenHeightPixels = metrics.HeightPixels;
                double screenDensity = metrics.Density;
    
                SupportFunctions.ScreenWidth = (int)(metrics.WidthPixels / screenDensity);
                SupportFunctions.ScreenHeight = (int)(metrics.HeightPixels / screenDensity);
    

    IOS:

            SupportFunctions.ScreenHeight = (int)UIScreen.MainScreen.Bounds.Height;
            SupportFunctions.ScreenWidth = (int)UIScreen.MainScreen.Bounds.Width;
    
            SupportFunctions.ScreenHeightPixels = (int)(UIScreen.MainScreen.Bounds.Height * UIScreen.MainScreen.Scale);
            SupportFunctions.ScreenWidthPixels = (int)(UIScreen.MainScreen.Bounds.Width * UIScreen.MainScreen.Scale);
    

    If you calculate your widths and heights in "form" units everything comes up the way you would expect.

Sign In or Register to comment.