currently Im using a Stacklayout with a BindingLayout like this:
<StackLayout BindableLayout.ItemsSource="{Binding MessstelleGeraete}" >
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout>
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0">
<---- some more stuff in here ---->
</StackLayout>
<StackLayout Grid.Row="0" Margin="-8,20,0,-20">
<BoxView Color="#0056AD" HeightRequest="2" WidthRequest="8" />
<BoxView Color="#0056AD" WidthRequest="2" HorizontalOptions="Start" VerticalOptions="FillAndExpand"/>
<BoxView Color="#0056AD" HeightRequest="2" WidthRequest="8" />
</StackLayout>
</Grid
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout
If for example we have 5 items in "MessstelleGeraete" then whe have a Stacklayout with 5 Stacklayouts in it. Inside of the 5 Stacklayouts there is 2 more Stacklayouts. The first contains some laybels and entries the second one contains 3 boxviews that look like "[". The "[" is as long as the entire Grid. When I shift it down with the margin its supposed to overlap onto the next (of our 5) stacklayouts. The Problem here is that the z-index inside a stacklayout is determined by the order of the child elements. Which means element 2 will overlap element 1 but I need it the other way around.
Left: "[" is cut off cuz Stacklayout 2/5 overlaps Stacklayout 1/5
How can I fix that? Can I use a RelativeLayout? If yes how?
Related
I am trying to lock the height of a header - or basically any kind of content on the top of a page. However, once scrollable content is added below the height changes. A simple example:
<ContentPage.Content>
<StackLayout Padding="0" Margin="0" Spacing="0">
<Frame Margin="0" HeightRequest="150" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
</StackLayout>
</ContentPage.Content>
This works fine. However, adding a lot of simple label lines in a scrollview somehow changes the height of the frame.
<ContentPage.Content>
<StackLayout Padding="0" Margin="0" Spacing="0">
<Frame Margin="0" HeightRequest="150" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
<ScrollView>
<StackLayout>
<Label Text="aaa" /> <!-- Repeated 54 times however removed here for simplicity-->
</StackLayout>
</ScrollView>
</StackLayout>
</ContentPage.Content>
The results end up like this:
Why does it happen and can I do anything to avoid it? And why is the height reduced to exactly that height? Thanks!
It doesn't seem like you're limiting the height of the ScrollView. So considering you're merely doing a HeightRequest, it may change as needed to fit everything.
It's usually safer to use Grids. In this example, something like this could help you:
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Frame Grid.Row="0" Margin="0" BackgroundColor="red" CornerRadius="0" HasShadow="False" Padding="0"></Frame>
<ScrollView Grid.Row="1">
<StackLayout>
<Label Text="aaa" /> <!-- Repeated 54 times however removed here for simplicity-->
</StackLayout>
</ScrollView>
</Grid>
</ContentPage.Content>
I am creating a car app that lists cars and their prices, model, speed, etc. I wanted to position the price over an image of the car, like so:
To do this, I created a grid and allowed the image to fill the entire thing while forcing the text (with a frame around it) into a lower column/row. However, I am ending up with white space on the top of the graph. Take a look. I set the grid to a background color of blue for easier viewing.
The issue here is the aspect ratio, because an image that did fill the entire grid would cut off the sides. The size of the whitespace is equivalent to the overlay, so if I had the overlay any lower that would result in more whitespace on both sides.
Note: Some of the cars have different aspect ratios, so this has to be a fix that would work for other images as well.
Note 2: This has to be a relative position fix, since obvious methods like setting the image's margin to -100 wouldn't work on other resolution screens and would probably get me fired.
The question: How can I relatively (e.g. make it work on every screen) force the image to the top of the page while still keeping the same aspect ratio and keeping the overlay?
Here's the front-end.
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="63*"/>
<ColumnDefinition Width="35*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3" Grid.RowSpan="2"/>
<Frame BackgroundColor="White" CornerRadius="5" Grid.Column="1" Grid.Row="1">
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
Move your frame not the image.
Set Grid content in one row.
Set Frame VerticalOptions to End
Set Frame HeightRequest and Margin (minus value).
Set bottom StackLayout VerticalOptions to FillAndExpand
<StackLayout>
<!-- Image and cost grid-->
<Grid BackgroundColor="Blue" ColumnDefinitions="63*, 35*, 2*">
<Image Source="{Binding ImageLocation}" Grid.ColumnSpan="3"/>
<!-- Shape the Frame here -->
<Frame HeightRequest="40" Margin="0,0,0,-20" VerticalOptions="End"
BackgroundColor="White" CornerRadius="5" Grid.Column="1" >
<Label Text="{Binding Cost}" FontSize="Large" HorizontalTextAlignment="End" TextColor="Black"/>
</Frame>
</Grid>
<!-- Information about the car -->
<StackLayout Padding="15" VerticalOptions="FillAndExpand">
<Label Text="{Binding Company}" FontSize="Large"/>
<Label Text="{Binding Model}" FontSize="Medium" FontAttributes="Bold"/>
</StackLayout>
</StackLayout>
I have a Grid with a few Rows defined. Within one of those rows is a single ScrollView. That ScrollView has a Grid with a single Image inside that's used as a sort of BackGround Image for one section. No matter what I do I cannot get the Image to Fill, AspectFill or AspectFit inside the Parent Grid (I have also tried a StackView to no avail). If I eliminate the ScrollView and pull the Grid and Image out the Image will Fit or Fill just fine.
Here is a stripped down example of what I'm doing:
<Grid ColumnSpacing="0" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"> ... </Grid>
<Grid Grid.Row="1"> ... </Grid>
<ScrollView Orientation="Vertical" HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" Grid.Row="2">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<!-- THIS IMAGE WILL NOT FILL! -->
<Image Source="{local:EmbeddedImage Project.Mobile.Images.fieldBackground.png}" Aspect="Fill" />
</Grid>
... More Code ...
</ScrollView>
</Grid>
No matter what I do the Image will not Fill the Grid Parent. If I remove the ScrollView it works just fine like this but I cannot do this without a ScrollView because I have more content directly below that cannot fit on the screen.
<Grid ColumnSpacing="0" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"> ... </Grid>
<Grid Grid.Row="1"> ... </Grid>
<Grid Grid.Row="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<!-- THIS IMAGE FILLS FINE! -->
<Image Source="{local:EmbeddedImage Project.Mobile.Images.fieldBackground.png}" Aspect="Fill" />
</Grid>
</Grid>
As a workaround I attempted to not aspect fit/fill the image but to anchor it at the top of the Grid and let it fill horizontally. But I cannot get the image to fit any other way inside the Grid besides centered vertically no matter what I try. If I make the Grid the exact height of the image it almost works but it looks different between iOS and Android. This seems like such a simple thing? What am I missing? I've wasted hours on this so far.
Thanks,
Any help is appreciated!
I would put the background image outside (below) the scrollview.
If you put both elements inside the same row/column in a grid, they will overlap.
The first child is at the back of the Z stack, the second child is placed above it, and so on.
<Grid ColumnSpacing="0" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="48"/>
<RowDefinition Height="4"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0"> ... </Grid>
<Grid Grid.Row="1"> ... </Grid>
<Image Grid.Row="2" Source="{local:EmbeddedImage Project.Mobile.Images.fieldBackground.png}" Aspect="Fill" />
<ScrollView Orientation="Vertical" HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" Grid.Row="2">
... Insert your elements here ...
</ScrollView>
</Grid>
I'm looking for a good way to implement a control that looks like a ListView with 2 columns, where each column has distinct height. As I didn't found another solution, I've decided to do it through a Repeater control.
The expected result is something like this:
All the items come from the same DataSource, and this DataSource will contain between one and a dozen of items.
The items must be splitted automatically (by modulo) into the 2 columns
When the user click on the button related to the item, this will open the item's detail page
The red squares are images that must have the same height/width
I'm working on the design of the cell DataTemplate, but I didn't see how to manage the images:
The distinction between the 2 columns is given by a Grid containing 2 Columns
Then I specify the DataTemplate for each column
<ScrollView>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Col.1 -->
<tabletControls:Repeater Grid.Column="0" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
<!-- Col.2 -->
<tabletControls:Repeater Grid.Column="1" Margin="10"
ItemsSource="{Binding ListProductItems}">
<tabletControls:Repeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" >
<StackLayout>
<ffimageloading:CachedImage Source="{Binding Icon}"
Aspect="AspectFill"/>
</StackLayout>
...
</StackLayout>
</ViewCell>
</DataTemplate>
</tabletControls:Repeater.ItemTemplate>
</tabletControls:Repeater>
</Grid>
</ScrollView
But this doesn't work as expected, as the image's height/width are not the same:
I already tried to play with Aspect (AspectFill, AspectFit, Fill) or VerticalOptions/HorizontalOptions, withou any result...
Is it possible to achieve the expected result without specify an HeightRequest? Are there other options?
I have a problem in my ListView on iOS. I can't adjust it to all iOS templates, ex: put HeightRequest = "855" on my iPhone 7 it already fits correctly, else on the iPhone 5 and smaller my ListView from a scrow. so I want my ListView to automatically adjust to the screen size.
<ListView x:Name="listView"
CachingStrategy="RecycleElement"
ItemsSource="{Binding FeedItems}"
HasUnevenRows="True"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1" HeightRequest="855">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackLayout HeightRequest = "60" WidthRequest="60">
<Image x:Name="Image" Source="{Binding Image}" Scale="1.0" Aspect="AspectFill" VerticalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Grid.Column="2" Spacing="4" VerticalOptions="Center">
<Label Text="{Binding Category}" TextColor="White" FontSize="Small" LineBreakMode="NoWrap" BackgroundColor="{Binding Color_category}"/>
<Label Text="{Binding PublishDate}" TextColor="#666666" FontSize="Small" LineBreakMode="NoWrap"/>
<Label Text="{Binding Title}" TextColor="#234084" Font="Bold" FontSize="Small" LineBreakMode="WordWrap"/>
</StackLayout>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
To expand a little more.
HeightRequest is used when you want to define a fixed size to an element. Xamarin will make its best to fulfill with this. In the other hand when you want your size to be relative you use the VerticalOptions and HorizontalOptions. This two properties will take a LayoutOptions struct and the default value for this is Fill (without expand).
This struct has two sets of properties, the ones I call "regular"
Center
Start
End
Fll
And the ones that "expands"
CenterAndExpand
StartAndExpand
EndAndExpand
FillAndExpand
You can read more about these here.
This last one FillAndExpand will take all the available space in the orientation it's used. This is the one you should use in your ListView to make it as big as the screen
Hope this helps.-