stacklayout with horizontal orientation, how to wrap vertically?

PippoCanePippoCane USMember ✭✭

as in the subject, how do I make a sequence of labels, horizontally stacked but wrapped vertically when needed?

Posts

  • MitchMilamMitchMilam USMember ✭✭✭

    On the label, set this property:

     LineBreakMode = LineBreakMode.WordWrap
    

    If the stack is inside of a Table, you need to make sure the RowHeight is set to allow all of the text. Otherwise, it will be cut off because all rows in a table are of the same height by default.

  • PippoCanePippoCane USMember ✭✭
    edited June 2014

    @MitcMilam Not what I intended, basically I have multiple words that I need to wrap in a box like a text editor. This is because I need to handle the tap on each one of the label separately. To be more precise, I expect a behavior similar to the StackPanel, where the horizontal orientation wraps vertically when the last child exceeds the width of the panel.

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    @PippoCane If you are referring to the WPF/SL/WinRT control StackPanel, it doesn't work that way.. it always extends infinitely in the orientation direction and never wraps. I think you might be thinking of WrapPanel which does what you want - wraps around on the edge boundaries. We don't currently have a WrapPanel type control .. I don't think it would be hard to make one though.

    I'm not completely clear on what you are trying to do - it sounds like you have multiple Label elements and you'd like them placed horizontally next to each other and have it wrap around when it hits the right hand edge.. can you give me a little more information and I'll try to point you in a good direction..

  • PippoCanePippoCane USMember ✭✭

    @msmith‌ Yes, sorry I was wrong, actually I was thinking of the WPF WrapPanel. In the final part of your answer you've got exactly the point, I want to render a list of hashtags in that way (with a tap gesture for each one).

  • RaviBhavnaniRaviBhavnani USMember, University

    @msmith‌
    The upgrade to Xamarin.Forms 1.2.1.6229 seems to have broken WrapLayout. In order to get it to compile, I had to delete the references to bindingPropertyChanged in the OrientationProperty and SpacingProperty definitions and add an override for OnPropertyChanged(), like so:

            protected override void OnPropertyChanged
                (string propertyName = null)
            {
                base.OnPropertyChanged(propertyName);
                if ((propertyName == WrapLayout.OrientationProperty.PropertyName) ||
                    (propertyName == WrapLayout.SpacingProperty.PropertyName)) {
                    this.OnSizeChanged();
                }
            }
    

    Thanks for a useful helper class!

  • ScottBradleyScottBradley AUMember ✭✭

    @RaviBhavnani‌ can you post what changes you made to these....

        /// <summary>
        /// Backing Storage for the Orientation property
        /// </summary>
        public static readonly BindableProperty OrientationProperty = 
            BindableProperty.Create<WrapLayout, StackOrientation> (w => w.Orientation, StackOrientation.Vertical, 
                bindingPropertyChanged: (bindable, oldvalue, newvalue) => ((WrapLayout)bindable).OnSizeChanged ());
    
        /// <summary>
        /// Orientation (Horizontal or Vertical)
        /// </summary>
        public StackOrientation Orientation {
            get { return (StackOrientation)GetValue (OrientationProperty); }
            set { SetValue (OrientationProperty, value); } 
    
  • RaviBhavnaniRaviBhavnani USMember, University

    Here you go:

    /// <summary>
    /// Backing Storage for the Orientation property
    /// </summary>
    public static readonly BindableProperty OrientationProperty = 
        BindableProperty.Create<WrapLayout, StackOrientation> (w => w.Orientation, StackOrientation.Vertical); 
    
    /// <summary>
    /// Orientation (Horizontal or Vertical)
    /// </summary>
    public StackOrientation Orientation {
        get { return (StackOrientation)GetValue (OrientationProperty); }
        set { SetValue (OrientationProperty, value); } 
    }
    
  • ScottBradleyScottBradley AUMember ✭✭

    Thanks Ravi.

  • KsuKsu USMember

    Does anyone know how to adjust controls width in WrapLayout?
    @PippoCane how did you manage the situation if tags have long names?

    I tried to change tag's name if its size is more then screen width. But the matter is that if agjust controls width inside OnSizeRequest - this method starts being called recursevely (on contlols size change event I suppose) and this messes up everything as a result...

  • omer.obaidomer.obaid USMember

    WrapLayout in Scroll View anyone tried this?

  • MyoKoMyoKo MMMember

    I have tried placing the Wrap Layout in Scroll View and created 100 buttons.
    The buttons are positioned just as expected but the scroll view does not scroll to all 100 buttons. It can be scrolled only to 80/90 buttons.
    I can see the edges of remaining buttons but can't scroll.

  • @MyoKo I solved this with introduce a bottom padding in the ScrollView (only tested on IOS)

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @MarkSmith.8123 said:
    @PippoCane‌ There isn't a panel built-in, but you can write one. Here's an example custom WrapLayout I whipped up to try it out. It's very simple and I'm not at all endorsing it as "how" to build layout controls. Also, keep in mind I did no real testing on this code.. so use it at your own risk, no guarantees, no maintenance, use however you like.. blah blah blah. You get it :)

    http://bit.ly/xf-custompanel

    @MarkSmith.8123
    I like your WrapPanel, but I'm wondering if there is a decent way to give it a bindable .ItemSource - just like a ListView.

  • MarkSmith.8123MarkSmith.8123 USXamarin Team, University, XamUProfessors Xamurai

    Hi @ClintStLaurent --

    Panels aren't intended to be bindable; so no. If you look at Grid, StackLayout, etc. none of them support that.

    Instead, what you really want is an ItemsControls -- a visual renderer that supports panel replacement. We don't have one yet, but you can get a reasonable start on it from here:

    https://github.com/xamarinhq/xamu-infrastructure/blob/master/src/XamU.Infrastructure/Controls/ItemsControl.cs

    This is from the XamU-Infrastructure library; the panel isn't replaceable, but you could change that pretty easily.

    I hope that helps!
    Mark Smith
    Xamarin University

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited November 2016

    @MarkSmith.8123
    Thanks Mark. In the last couple hours since I originally posted that I made a BindableWrapLayout by taking a WrapLayout class we had (but didn't have binding) and an ItemsView class that was bindable but not wrapping, and merge their functionality. Usage then becomes rather friendly and close enough to what I would expect from a WPF WrapPanel

                    <controls:BindableWrapLayout Grid.Row="1"
                                                 Grid.Column="0"
                                                 Grid.ColumnSpan="5"
                                                 ItemsSource="{Binding Items, Source={x:Reference this}}"
                                                 Orientation="Horizontal"
                                                 Spacing="10">
                        <controls:BindableWrapLayout.ItemTemplate>
                            <DataTemplate>
                                <Grid HeightRequest="60"
                                      WidthRequest="210"
                                      BackgroundColor="{StaticResource BlueTextColor}">
                                    <Label HorizontalOptions="CenterAndExpand"
                                           VerticalOptions="CenterAndExpand"
                                           HorizontalTextAlignment="Center"
                                           VerticalTextAlignment="Center"
                                           FontAttributes="Bold"
                                           BackgroundColor="{StaticResource BlueTextColor}"
                                           Text="{Binding FriendlyName,
                                                          Mode=OneWay}"
                                           TextColor="{StaticResource TagForegroundColor}"
                                           Style="{StaticResource LabelStyleMed}" />
                                </Grid>
                            </DataTemplate>
                        </controls:BindableWrapLayout.ItemTemplate>
                    </controls:BindableWrapLayout>
    
  • YuraBabiyYuraBabiy UAMember ✭✭✭
    edited December 2016

    @ClintStLaurent
    Can you please share your code of the BindableWrapLayout? It will be fantastic if it is full.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    I can't because its part of a project that is not yet released to the public and like being employed and feeding my family.

    What I can say is there are various open source wrap panels out there. And there are several different controls that do binding. If you dissect a few and take the best parts of a few of them {...} Not to mention the learning potential of studying code more advanced than one's current skillset - its a big part of how we all grow.

  • YuraBabiyYuraBabiy UAMember ✭✭✭

    @ClintStLaurent
    I understand you. And you are completely right about studying. I will try. Anyway, thank you :wink:

Sign In or Register to comment.