How to adjust comportment of StackLayout and its contents?

Hello,
I need to "port" a web application on Xamarin for a customer. As this is my first Xamarin.Forms application, I ask me a lot of questions about the design.

If I base on the web app, the screen is composed in 4 areas :

1. this first area contains:
- 2 Entries and 2 Buttons in the first row
- 1 ListView as "main row"
- 1 Entry in the third row
2. the second area contains:
- a lot of "action" Buttons (this number is fixed)
3. the third area contains:
- a lot of "family items" Buttons (these items are obtained by a call to a WebService the first time that the screen is displayed)
4. the last area contains:
- a lot of "details items" Buttons (these items are obtained by a call to a WebService when we click on a "first level item" Button)

Thus, the app might look like this with the original assets:

So, I think the best way to do this is to use:

  • a main "vertical" StackLayout that contains all the content
  • a Grid of 3 rows and 2 columns that contains the 2 first areas
  • 2 "horizontal" StackLayout that contains the 2 last areas

The XAML could looks like this:
`

<!-- First and second areas -->
<Grid>

  <Grid.RowDefinitions>
    <RowDefinition Height="auto" />
    <RowDefinition Height="*" />
    <RowDefinition Height="auto" />
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="2*" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>

  <!-- Line 1 of the Grid -->
  <StackLayout Grid.Row="0"
               Grid.Column="0"
               Orientation="Horizontal">

    <Entry Text="On site" />
    <Entry Text="3" />
    <Button Text="^" />
    <Button Text="v"/>
  </StackLayout>

  <!-- Line 2 of the Grid -->
  <ListView Grid.Row="1"
            Grid.Column="0" />

  <!-- Line 3 of the Grid -->
  <Entry Grid.Row="2"
         Grid.Column="0"
         Text="TOTAL" />

  <!-- Column 2 of the Grid -->
  <StackLayout Grid.Column="1"
               Grid.RowSpan="3"
               Orientation="Horizontal" >
    <Button Text="A1" />
    <Button Text="A2" />
    <Button Text="A3" />
    <Button Text="A4" />
    <Button Text="A5" />
    <Button Text="A6" />
    <Button Text="A7" />
    <Button Text="A8" />
  </StackLayout>

</Grid>

<!-- StackLayout "Family" -->
<StackLayout Orientation="Horizontal">
  <Button Text="Family 1" BackgroundColor="Red" />
  <Button Text="Family 2" BackgroundColor="Yellow" />      
</StackLayout>

<!-- StackLayout "Details" -->
<StackLayout Orientation="Horizontal">
  <Button Text="Details 1" BackgroundColor="Red" />
  <Button Text="Details 2" BackgroundColor="Red" />
  <Button Text="Details 3" BackgroundColor="Red" />
  <Button Text="Details 4" BackgroundColor="Red" />
</StackLayout>

`

But the rendering is not consistent with what I expected:

- the "action" buttons (A1, A2, ...) to the right of the ListView take all the available space as height
- the horizontal StackLayouts containing buttons don't expand and don't push their content to the line

So I wonder several questions:
- Is it possible to force a StackLayout to expand itself, for allowing its content (the Buttons) to go back to the line?
I tried to play with "HorizontalOptions" and "VerticalOptions", without any result.
- How can I force a button to not take all the available space from its parent for height?
I tried to set a "HeightRequest" value, without any result.
- Is it possible to load buttons dynamically with binding, or do I need to do this by code?
The buttons of my third and fourth areas will be loading dynamically from a JSON.
- Finally, do you think that my approach to display this screen is correct (Stack Layout > Grid | StackLayout | StackLayout), or is a better way to do this?
For example, I don't know how to specify the "ideal" width for the ListView (currently the value is given with the ColumnDefinition fixed to "2*").

Posts

  • alessandrosuppiejalessandrosuppiej ITMember ✭✭
    edited December 2015

    Hi Pierre.

    I'd try this solution :

    < StackLayout Grid.Column="1" Grid.RowSpan="3" Orientation="Vertical" >
    < StackLayout bla bla bla Orientation = "Horizontal">
    < Button A1>
    < Button A2>
    < /StackLayout>
    < StackLayout bla bla bla Orientation = "Horizontal">
    < Button A3>
    < Button A4>
    </ StackLayout>
    </ StackLayout>

    ps : forgive me but i'm not able to insert code in the chat.

    Let me know if it behave as expected.
    Cheers
    Alessandro

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭

    Hi Alessandro, thanks for your return.
    Your solution partially works for the "static" buttons which are defined in the XAML.
    But how manage the other buttons, which are loaded "dynamically" ? Isn't there a way to set parameters of the StackLayout?
    Also, can I add buttons in a StackLayout by binding or must I do it by the code?

  • If you're talking about the fourth area (with dinamically loaded contents) i suggest to use a listview.
    (i came from wpf and i'm not sure of exact name matching with xamarin forms).

    A listview can contain an ObservableCollection .
    When you work with ObservableCollections, your view is automatically updated.

    When you use a listview, you should define your ItemTemplate (i think here it's called something like Cell)
    ItemTemplate can be completely customized. it's a separate xaml that contains all of the behaviours of the cell.

    So, your binding is done by your List and you don't need to manually load controls into the stacklayout.

    A.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    To help the last guy out:

    Here is the Xamarin ListView tutorial.

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭

    @alessandrosuppiej said:
    If you're talking about the fourth area (with dinamically loaded contents) i suggest to use a listview.
    (i came from wpf and i'm not sure of exact name matching with xamarin forms).

    A listview can contain an ObservableCollection .
    When you work with ObservableCollections, your view is automatically updated.

    When you use a listview, you should define your ItemTemplate (i think here it's called something like Cell)
    ItemTemplate can be completely customized. it's a separate xaml that contains all of the behaviours of the cell.

    So, your binding is done by your List and you don't need to manually load controls into the stacklayout.

    A.

    I know the ListView that I use to display items in the second line of my first area.
    But for the third and fourth area, it doesn't seem appropriate cause I want to display buttons in "inline" mode: I want show the most of buttons possible in a row before returning to the line.

  • RohitKumarRohitKumar USMember, University
    edited December 2015

    Did you try in designer in Android or IOS and see the layouts...

    Anyways, there are ways you can dynamically catch the event under OnSizeChanged.. and handle it.

  • Dear Pierre, i understand your point of view but my question is : do you think you can easilly do something better than
    framework tools?
    I think you can reach your goal and you can override stacklayout capabilities to accomplish your needs.
    But i ask you the reason to do that if you have a powerful tool ready to use.
    If you want to do this overriding for your own exercise i appreciate it but i'm not sure that costs/benefits ratio is good.

    However i'm happy to discuss of these arguments with the community. This is the only way to improve our skills.

    (and i am always ready to learn from your ideas.... )
    A.

  • Pierre-ChristopheDusPierre-ChristopheDus FRUniversity ✭✭✭
    edited December 2015

    Hi alessandro, I don't think that I can easily do something better than framework tools. But as it's my first project, I don't know if it's about limits of the framework or limits of my knowledges ;-)

    For example, the ListView as you mentioned could be a good alternative if I can use it "horizontally". But I don't find example of how to implement it...

Sign In or Register to comment.