0

I have the following XAML in my Xamarin Forms project

    <StackLayout x:Name="slFullPage" Orientation="Vertical" HorizontalOptions="Fill" VerticalOptions="FillAndExpand" Margin="0,0,0,0" BackgroundColor="AliceBlue">
        <localapp:PageHeader x:Name="pgHeader" VerticalOptions="Start" HorizontalOptions="Fill" />
        <combobox:SfComboBox x:Name="cmbLanguage" DataSource="{Binding LangaugesByAppLanguage}" TextSize="Micro" 
                             TextColor="#283655" SelectionChanged="cmbLanguage_SelectionChanged"
                             Watermark="{localapp:Translate SelectValue}" DropDownItemHeight="25" WidthRequest="250" HeightRequest="30"
                             DropDownTextSize="Micro" BackgroundColor="White" HorizontalOptions="Center" VerticalOptions="Start"
                             DisplayMemberPath="LanguageName" SelectedValuePath="ISO_639_1_Code">
        </combobox:SfComboBox>
        <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="End" BackgroundColor="Aqua">
            <buttons:SfButton x:Name="btnCancel" Text="{localapp:Translate Cancel}" HorizontalOptions="Start" VerticalOptions="End" Margin="8,0,4,0"/>
            <buttons:SfButton x:Name="btnDone" Text="{localapp:Translate Done}" HorizontalOptions="End" VerticalOptions="End" Margin="4,0,8,0"/>
        </StackLayout>
        <localapp:AppFooter x:Name="pgFooter" VerticalOptions="End" HorizontalOptions="Fill" />
    </StackLayout>

Based on my understanding of the horizontal options that can be specified on an object, I would expect the Cancel button to be at the start of my horizontal stack layout and my Done button to be at the end of the same stack layout.

Additionally, based on the vertical options that can be used, I would expect the stacklayout with the buttons in it as well as my appfoot to appear at the bottom of my slFullPage stack layout. However, neither of those things are happening.

Instead what I get can be seen below:

enter image description here

You can see that the entire page stacklayout is going all the way to the bottom of the screen but my buttons and footer are not at the bottom.

Additinally, you can see the horizontal stack layout (aqua) goes all the way across the screen but the buttons are not positioned based on their horizontal options.

Any ideas?? FYI - I am running the project as a UWP app.

George M Ceaser Jr
  • 1,497
  • 3
  • 23
  • 52

2 Answers2

0

You don't want to use a StackLayout (well 2 StackLayout), but a Grid:

It's more convenient for your layout, and it is way more performant.

<Grid ColumnSpacing="0" RowSpacing="0">
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="40" />
        <RowDefinition Height="40" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinition>
        <ColumnDefinition Width="80" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="80" />
    </Grid.ColumnDefinition>

    <localapp:PageHeader Grid.Row="0" x:Name="pgHeader" />

    <combobox:SfComboBox Grid.Row="1" x:Name="cmbLanguage" DataSource="{Binding LangaugesByAppLanguage}" TextSize="Micro" 
                         TextColor="#283655" SelectionChanged="cmbLanguage_SelectionChanged"
                         Watermark="{localapp:Translate SelectValue}" DropDownItemHeight="25" WidthRequest="250"
                         DropDownTextSize="Micro" BackgroundColor="White" HorizontalOptions="Center"
                         DisplayMemberPath="LanguageName" SelectedValuePath="ISO_639_1_Code">
    </combobox:SfComboBox>

    <buttons:SfButton Grid.Row="2" Grid.Column="0" 
                      x:Name="btnCancel" Text="{localapp:Translate Cancel}"  Margin="8,0,4,0"/>
    <buttons:SfButton Grid.Row="2" Grid.Column="2" 
                      x:Name="btnDone" Text="{localapp:Translate Done}" Margin="4,0,8,0"/>
</Grid>
Roubachof
  • 3,351
  • 3
  • 23
  • 34
  • No I don't want to use a grid. Grid had built in padding spacing and its own issues. I want to use a stack layout. – George M Ceaser Jr Sep 18 '19 at 00:35
  • Just put default padding to 0 like I always do. It's a shame people doesn't understand grid and use nested stacklayout instead. It has a bad impact on performance... https://ericsink.com/entries/xf_measure.html – Roubachof Sep 18 '19 at 06:43
  • I am not using grids. I do understand them. I prefer to use stack layouts for a variety of reasons. – George M Ceaser Jr Sep 19 '19 at 13:44
0

Based on my understanding of the horizontal options that can be specified on an object, I would expect the Cancel button to be at the start of my horizontal stack layout and my Done button to be at the end of the same stack layout.

You could use a AbsoluteLayout to make the buttons positioned anywhere within a view.

<AbsoluteLayout BackgroundColor="LightBlue" HeightRequest="60" VerticalOptions="EndAndExpand">
        <Button Text="Cancel" Margin="10,10" BackgroundColor="DarkBlue" TextColor="White"/>
        <Button Text="Done" Margin="10,10" AbsoluteLayout.LayoutBounds="1, 0, AutoSize, AutoSize" AbsoluteLayout.LayoutFlags="PositionProportional" BackgroundColor="DarkBlue" TextColor="White"/>
</AbsoluteLayout>

And use the VerticalOptions="EndAndExpand" to make it appears at the end of its parent and expands.

Updated:

I do not know what it was before, but for now, it doesn’t actually fill up the space in the StackLayout. It’s only when the fill option is used, that it will expand to that space.

When you expect the Cancel button to be at the start and the Done button to be at the end of the same stack layout, fill option and expend need to be setted. I use simple example to display.

<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand" BackgroundColor="Aqua">
            <Button x:Name="btnCancel" Text="Cancel" HorizontalOptions="StartAndExpand" Margin="8,0,4,0"/>
            <Button x:Name="btnDone" Text="Done" HorizontalOptions="EndAndExpand" Margin="4,0,8,0"/>
</StackLayout>

And if you do not want space between last two lines in the end, you need a nested stacklayout to do that without space.

Simple code:

 <StackLayout BackgroundColor="LightGray">
    <StackLayout>
        <Entry  x:Name="pgHeader" Text="pgHeader"  HorizontalOptions="FillAndExpand" />
        <Entry x:Name="cmbLanguage" Text="cmbLanguage" WidthRequest="250" HeightRequest="30"
                          BackgroundColor="Red" HorizontalOptions="CenterAndExpand" ></Entry>

    </StackLayout>

    <StackLayout  HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand">
        <StackLayout Orientation="Horizontal"  BackgroundColor="Aqua">
            <Button x:Name="btnCancel" Text="Cancel" HorizontalOptions="StartAndExpand" Margin="8,0,4,0"/>
            <Button x:Name="btnDone" Text="Done" HorizontalOptions="EndAndExpand" Margin="4,0,8,0"/>
        </StackLayout>
        <Entry x:Name="pgFooter" Text="pgFooter"/>
    </StackLayout>
</StackLayout>

enter image description here

Wendy Zang - MSFT
  • 10,509
  • 1
  • 7
  • 17
  • Thank you for the information. I am aware there are other ways to accomplish what I am trying to do. However, my question is why doesn't what I am doing work correctly? I believe it has worked in the past. – George M Ceaser Jr Sep 18 '19 at 13:08
  • I have updated my reply to explain and how to do that in `stacklayout`. – Wendy Zang - MSFT Sep 19 '19 at 03:32
  • WendyZang the button thing seemed to work with a stacklayout inside a stacklayout. Not sure why this is needed but works. – George M Ceaser Jr Sep 23 '19 at 13:28
  • @GeorgeMCeaserJr Because when you want to let the two lines (one is cancel and down button and the other is pgFooter) in the end without space between them, it would be better to put them in one stacklayout, otherwise, it would show space between them instead of both of them would be in the end. – Wendy Zang - MSFT Sep 25 '19 at 03:26