Xamarin.Forms BoxView Height match Width - xaml

I am trying to get the box view of a content page to 'FillAndExpand' horizontally while making the height equal to it's width. So far for the xaml I've got:
<ContentPage Title="About" >
<StackLayout>
<BoxView x:Name ="imageBoxView" Color="AliceBlue" HorizontalOptions="FillAndExpand" />
</StackLayout>
</ContentPage>
But I don't know what value to keep for the Height Request.

You can set the binding context to itself, and then bind the HeightRequest to the view's Width.
Note: This will not work in the XAML preview mode in Visual Studio, but will work at runtime on the device.
<StackLayout>
<BoxView x:Name ="imageBoxView" Color="AliceBlue"
HorizontalOptions="FillAndExpand"
BindingContext="{x:Reference imageBoxView}"
HeightRequest="{Binding Width}" />
</StackLayout>

Related

How To Use Different Alignments for Elements in XAML AbsoluteLayout (Xamarin.Forms)

In the following XAML, I have a Frame that contains an AbsoluteLayout that contains an Image and a Label. I want the Image to be left justified and the Label to be centered (in the entire AbsoluteLayout object). Here is my XAML:
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<AbsoluteLayout BackgroundColor="Black">
<Image Source="{local:ImageResource App.Raindrops.png}"
WidthRequest="40"
HeightRequest="60" />
<Label Text="Sprinkle"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="White"
FontSize="36"/>
</AbsoluteLayout>
</Frame>
No matter what HorizontalOptions and VerticalOptions I use, I always get the following...
Notice that the label is not centered. Am I using the wrong layout? Am I missing, or using some wrong, attributes?
I am building the application in Visual Studio as a Xamarin.Forms app, and the deployment is being done to the standard Visual Studio Android emulator.
I found one solution here (which also has a great discussion on overlaying in XAML). The modified XAML is:
<Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0">
<AbsoluteLayout BackgroundColor="Black">
<Image
Source="{local:ImageResource App.Raindrops.png}"
WidthRequest="50"
HeightRequest="60"/>
<Label
Text="Sprinkle"
TextColor="White"
FontSize="36"
AbsoluteLayout.LayoutBounds="0.5, 0.5, -1, -1"
AbsoluteLayout.LayoutFlags="PositionProportional"/>
</AbsoluteLayout>
</Frame>
... and the result is this ...
... which is exactly what I wanted.
By the way, I came across this little tidbit in the documentation page for AbsoluteLayout:

Xamarin.Forms: how to automatically hide first CollectionView

I work on a Xamarin.Forms app that will contain a page with 2 CollectionView items:
an horizontal CollectionView that will display events
a vertical CollectionView that will display posts
I would like that the first list is progressively hidden as soon as the user starts to scroll on the second list.
We can found this behaviour on a sample from Syncfusion: but they use a SfRotator as control for the horizontal list:
I've tried to reproduce the same behaviour on my page, but it doesn't work as expected. My horizontal list is not hidden until I scroll vertically on this first list itself. If I scroll on the second vertical list, the first list is still visible:
My XAML looks like this:
<ContentPage.Content>
<RefreshView x:DataType="vm:NewsViewModel"
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<ScrollView>
<StackLayout Padding="16" Spacing="16">
<CollectionView x:Name="EventsListView"
ItemsSource="{Binding Events}"
HeightRequest="250"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame BackgroundColor="Red">
<StackLayout x:DataType="model:Event" >
<Label Text="{Binding Name}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<CollectionView x:Name="NewsListView"
ItemsSource="{Binding News}"
VerticalScrollBarVisibility="Never"
SelectionMode="None">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ctrl:ShadowFrame>
<StackLayout x:DataType="model:News">
<Label Text="{Binding Description}" />
<Label Text="{Binding Date}" />
<Image Source="{Binding Image}" />
</StackLayout>
</ctrl:ShadowFrame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ScrollView>
</RefreshView>
</ContentPage.Content>
=> Is there a way to achieve this?
Quick reminder that you Shouldn't use Scrollable Elements inside other Scrollable Element, it usually breaks how both work, Quoting:
Xamarin doesn't recommend using the ListView, WebView, or ScrollView
inside a ScrollView. Microsoft Xamarin.Forms Official Documentation
says that ScrollViews should not be nested. In addition, ScrollViews
should not be nested with other controls that provide scrolling, like
ListView and WebView.
And this is what happening:
The ScrollView isn't actually scrolling, the Vertical CollectionView is the one giving the Illusion that the page is scrolling, meaning that the Horizontal one is always on top.
How to fix it?
To fix this, you should remove the Vertical CollectionView and use some kind of Repeater View, this Post will guide you on how to achieve it.

How do I force child controls or layouts to be the same width as the parent in Xamarin Forms?

I have the following code.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="NGIC_XAML.Views.Payments.Payments">
<ContentPage.Content>
<FlexLayout Direction="Column" AlignItems="Center" HorizontalOptions="FillAndExpand">
<StackLayout BackgroundColor="Red" HeightRequest="108" HorizontalOptions="FillAndExpand">
<Label Text="Payments" TextColor="#F9F8FA" FontSize="20" Margin="40"
HorizontalTextAlignment="Center" VerticalOptions="Center"
HorizontalOptions="FillAndExpand">
</Label>
</StackLayout>
</FlexLayout>
</ContentPage.Content>
</ContentPage>
I want the outer layout, the FlexLayout, to automatically size the width to the device's maximum. I want the Layout (the StackLayout) and child Control (the Label), to also automatically resize their widths to the FlexLayout. I am stumped as to how to do this. Any suggestions?
In the FlexLayout docs, they mention "The HorizontalOptions property doesn't work for children of a FlexLayout".
If you take a look at the Page layout with FlexLayout section (Holy Grail Layout) you can see an example somewhat similar to what you are trying to accomplish, basically use a nested FlexLayout instead of a StackLayout.
The code would look like:
<ContentPage.Content>
<FlexLayout
BackgroundColor="Yellow"
Direction="Column">
<FlexLayout
HeightRequest="108"
AlignItems="Center"
Direction="Column"
BackgroundColor="Red">
<Label
BackgroundColor="Green"
LineBreakMode="CharacterWrap"
Text="Payments"
TextColor="#F9F8FA"
FontSize="20"
Margin="40"
HorizontalTextAlignment="Center"
VerticalOptions="Center">
</Label>
</FlexLayout>
</FlexLayout>
</ContentPage.Content>
And here is the screenshot:
Notice that the label will grow as needed to use the full width of the row.
To achieve this, please assign HorizontalOptions="FillAndExpand" to StackLayout and Label and other child controls if any.
This will tell the controls to fill all the space available horizontally.
Thanks!

ListView taking more height than needed and Entry being hidden

I am working on a Xamarin.Forms PCL project.
I am working on a page that displays a post, the comments for that post, and an Entry to write a comment.
My XAML is
<ContentPage.Content>
<StackLayout>
<ScrollView>
<StackLayout>
<StackLayout>
<local:PostListView x:Name="Post" ItemTemplate=...>
</local:PostListView>
</StackLayout>
<StackLayout>
<Label x:Name="CommentHeader" FontSize="15" FontAttributes="Bold" HorizontalOptions="CenterAndExpand"/>
<ListView x:Name="CommentsList" HasUnevenRows="True" SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<local:PostViewCell>
...
</local:PostViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</StackLayout>
</ScrollView>
<StackLayout>
<StackLayout x:Name="CommentBox" Padding="10, 5, 10, 10">
<Entry x:Name="CommentEntry" Placeholder="Comment" BackgroundColor="GhostWhite" Focused="CommentEntry_Focused" Unfocused="CommentEntry_Unfocused" TextChanged="CommentEntry_TextChanged"/>
</StackLayout>
</StackLayout>
</StackLayout>
</ContentPage.Content>
The first custom ListView displays only a single post at a time but I use to so I can use the ItemTemplate feature.
My problems are:
The whole page should scroll together (leaving the comment entry) but the first ListView covers the whole screen and only shows the comment ListView once you scroll down, it only needs about 1/5 of the page the rest is blank white space.
The comment entry is supposed to sit on the bottom of the page but appear ontop the keyboard when focused but instead gets covered by the keyboard.
For The First point you can try Grid Instead Of Stack Layout to be able control the portion of each Container.
About the second Point I suggest you take a look at
https://github.com/paulpatarinski/Xamarin.Forms.Plugins/tree/master/KeyboardOverlap

Frame doesn't obey HeightRequest

Can you guys please explain why the Frame doesn't respect the HeightRequest or WidthRequest?
Using those properties in other controls it works as expected.
For example, in this XAML I'm using a Frame and a BoxView:
<StackLayout Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
Padding="10">
<Frame VerticalOptions="Center"
HeightRequest="5"
WidthRequest="5"
BackgroundColor="Red"/>
<BoxView VerticalOptions="Center"
HeightRequest="5"
WidthRequest="5"
Color="Blue"/>
</StackLayout>
And the result is:
There is a big difference between the Frame's size and box's size, but it shouldn't have.
Frame has a default padding of 20. Set Padding="0".
See the remarks here: https://developer.xamarin.com/api/type/Xamarin.Forms.Frame/