Xamarin.Forms - My ControlTemplate doesn't respect HeightRequest - xaml

I have created a BottomBar in my App.xaml and I am using ControlTemplate to call it into the Xaml file of a different page.
My problem is: I have tried using HeightRequest inside the Layout in my App.xaml file, also tried using it in the Xaml file of the other page when calling it, and nothing seems to work. The page doesn't respect the HeightRequest.
I want them all to have the same height on every page (60).
page1
page2
page3
As you can see, the bottom bar has a different size on each page.
My App.xaml:
<ControlTemplate x:Key="CartTemplate" >
<AbsoluteLayout
x:Name="CartSection"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="#004EFF"
HeightRequest="60">
<Image Source="caricon"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"
AbsoluteLayout.LayoutBounds="0.5,0.5"
AbsoluteLayout.LayoutFlags="PositionProportional"/>
<Grid
HeightRequest="22"
IsVisible="{TemplateBinding BindingContext.OrderCountVisible}"
WidthRequest="22"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
AbsoluteLayout.LayoutBounds="0.5,0.5"
AbsoluteLayout.LayoutFlags="PositionProportional"
Padding="25,0,0,10">
<Ellipse Fill="White"/>
<Label
Text="{TemplateBinding BindingContext.cartNumberItems}"
HorizontalOptions="CenterAndExpand"
TextColor="#004EFF"
FontAttributes="Bold"
FontSize="14"
Padding="0,0,0,3"
FontFamily="{StaticResource Helvetica}"/>
</Grid>
<AbsoluteLayout.GestureRecognizers>
<TapGestureRecognizer Command="{TemplateBinding BindingContext.CarCommand}" />
</AbsoluteLayout.GestureRecognizers>
</AbsoluteLayout>
</ControlTemplate>
This is how I am calling the Template (At the bottom just above the end tags):
<TemplatedView ControlTemplate="{StaticResource CartTemplate}"/>
</StackLayout>
</ContentPage.Content>
Thanks in advance.

Related

Stretch BindableLayout.ItemTemplate in Maui horizontally

I have a HorizontalStackLayout with elements in it added via the BindableLayout.Itemsource.
This is an example of what I mean:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="StackLayoutStretchTest.MainPage">
<VerticalStackLayout>
<HorizontalStackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Green">
<BindableLayout.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</BindableLayout.ItemsSource>
<BindableLayout.ItemTemplate>
<DataTemplate>
<Label Text="{Binding .}"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
TextColor="White"
BackgroundColor="DarkBlue"/>
</DataTemplate>
</BindableLayout.ItemTemplate>
</HorizontalStackLayout>
<VerticalStackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Label Text="Text"
HorizontalTextAlignment="Center"
TextColor="Black"
BackgroundColor="White"/>
</VerticalStackLayout>
</VerticalStackLayout>
</ContentPage>
How can I make the Labels(Blue) FillAndExpand into the free space(Green)?
The Maui learn page says:
A HorizontalStackLayout only respects the alignment preferences on
child views that are in the opposite direction to the orientation of
the layout.
Is there a way to stretch the children, or what is the appropriate "container" for this use case?
Please be noted that it's a known issue that being tracked in [Bug] LayoutOptions Expand not work in HorizontalStackLayout and VerticalStackLayout . To be clear, the AndExpand options are deprecated, and are not supported in the new HorizontalStackLayout and VerticalStackLayout. As an alternative solution, you can achieve the same layout with a Grid. Or you can continue to use StackLayout for another choice.

Resume and modify some graphic elements present in another page

I have created a ControlTemplate in the app.xaml, defining the graphic part, only in the cs I would like to take some elements, to which I have given the name, to assign them the click event, but it signals me that they do not exist in the current context .
Someone who could kindly tell me how to please?
Someone, if possible, modify the source of the webview present in the main page, directly from app.xaml.cs
My code in the template is this:`
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="HeaderFooterTemplate"><ContentPresenter />
<StackLayout>
<BoxView HorizontalOptions="FillAndExpand" BackgroundColor="#DDDDDD" HeightRequest="2" Margin="0" />
<ScrollView Orientation="Horizontal">
<Grid RowSpacing="0">
<StackLayout Background="#c9ced6" HeightRequest="120" MinimumHeightRequest="120" Orientation="Horizontal" Grid.Row="0" Spacing="2">
<Grid WidthRequest="100" MinimumHeightRequest="120" BackgroundColor="#373B53" Padding="10" x:Name="Dashboard">
<Image Source="homeArancione" x:Name="imgDashboard" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="30" HeightRequest="30" Grid.Row="0" />
<Label Text="DASHBOARD" TextColor="#c9ced6" FontAttributes="Bold" HorizontalOptions="Center" Grid.Row="1" />
</Grid></Grid>
And in the reference page I recall it like this:
ControlTemplate="{StaticResource HeaderFooterTemplate}"
Graphically it works, but in the cs is I can't modify the texts to the labels or assign click events to the elements because it tells me that they don't exist in the current context
If you want to change the text or trigger the click event of the label in ControlTemplate, you could use the GestureRecognizers. The x:Name could not be found in the ControlTemplate directly.
<ControlTemplate x:Key="HeaderFooterTemplate">
<!--<ContentPresenter />-->
<StackLayout>
<BoxView HorizontalOptions="FillAndExpand" BackgroundColor="#DDDDDD" HeightRequest="2" Margin="0" />
<ScrollView Orientation="Horizontal">
<Grid RowSpacing="0">
<StackLayout Background="#c9ced6" HeightRequest="120" MinimumHeightRequest="120" Orientation="Horizontal" Grid.Row="0" Spacing="2">
<Grid WidthRequest="100" MinimumHeightRequest="120" BackgroundColor="#373B53" Padding="10" x:Name="Dashboard">
<Image Source="homeArancione" x:Name="imgDashboard" HorizontalOptions="Center" VerticalOptions="Center" WidthRequest="30" HeightRequest="30" Grid.Row="0" />
<Label Text="DASHBOARD" TextColor="#c9ced6" FontAttributes="Bold" HorizontalOptions="Center" Grid.Row="1">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</Label.GestureRecognizers>
</Label>
</Grid>
</StackLayout>
</Grid>
</ScrollView>
</StackLayout>
</ControlTemplate>
Code behind: App.xaml.cs
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
Console.WriteLine("-----------");
var label = sender as Label;
label.Text = "Hello";
}
Update:
update the text of the label as soon as the page loads, without
having to click
Xamarin provide GetTemplateChild to get a named element from a template. The GetTemplateChild method should only be called after the OnApplyTemplate method has been called. If you want to call the OnApplyTemplate method, this template should be added for the contentpage.
You could refer to the thread i done before.
Xamarin SwipeView Open Left Item In ControlTemplate

TapGesture won't fire when adjusted inside a layout Xamarin

So basically I have an annoying thing when I'm trying to adjust my frame inside an AbsoluteLayout such:
<AbsoluteLayout Grid.Column="4">
<Frame CornerRadius="20"
Padding="0"
BorderColor="#9f6b34"
Background="Transparent">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="fourthButton_Clicked"/>
</Frame.GestureRecognizers>
<Label Text="Classic and traditional"
Padding="35"
FontSize="40"
FontFamily="font2"
HorizontalTextAlignment="Center"
TextColor="#211717">
</Label>
</Frame>
When the code is like this it's fine but when I try to adjust the frames' position with .LayoutBounds it just won't click. I've tried changing it to a StackLayout and click event fires sometimes in various different positions inside the frame. I've put ImageButton, regular button and also tried using my label's GestureRecognizer but it just won't click when I made adjustments.
here is a gif of the situtation. the top frame isn't adjusted the bottom one is
When the code is like this it's fine but when I try to adjust the frames' position with .LayoutBounds it just won't click.
I try your code, and it works fine, having no problem, please take a look the following code:
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<AbsoluteLayout>
<Frame
Padding="0"
AbsoluteLayout.LayoutBounds="0, 10, 300, 200"
BorderColor="#9f6b34"
CornerRadius="20">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="fourthButton_Clicked" />
</Frame.GestureRecognizers>
<Label
Padding="35"
FontFamily="font2"
FontSize="40"
HorizontalTextAlignment="Center"
Text="Classic and traditional"
TextColor="#211717" />
</Frame>
</AbsoluteLayout>
<StackLayout Grid.Row="1">
<Frame
Padding="0"
BorderColor="#9f6b34"
CornerRadius="20">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="fourthButton_Clicked" />
</Frame.GestureRecognizers>
<Label
Padding="35"
FontFamily="font2"
FontSize="40"
HorizontalTextAlignment="Center"
Text="Classic and traditional"
TextColor="#211717" />
</Frame>
</StackLayout>
</Grid>
</StackLayout>
I put Frame in AbsoluteLayout and also use AbsoluteLayout.LayoutBounds to adjust Frame poaition, I also put frame in StackLayout, it also works fine.

How to set z-index on a control within AbsoluteLayout in xaml?

I have an AbsoluteLayout on a view in my Xamarin.Forms app, with 3 buttons in it. After another control is added programmatically, it covers the buttons. I cannot figure out how I can make the buttons to be always in front.
<ContentPage.Content>
<AbsoluteLayout x:Name="Container" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Button
Style="{StaticResource CallButtonStyle}"
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".85,.02"
Text="{Binding CameraSwitchIcon}" />
<Button
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".15,.95,80,80"
Text="{Binding VideoToggleIcon}" />
<Button
...
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds=".85,.95,80,80"
Text="{Binding AudioToggleIcon}" />
</AbsoluteLayout>
</ContentPage.Content>
all XF Layouts have RaiseChild() and LowerChild() methods you can use to adjust the Z index

Xamarin Style IndicatorView to look like TabbedPage

I have a problem. I recently had this problem: Xamarin forms Add button in TabbedPage, but that is fixed using the accepted anwser. In short, I am using a CarouselView and an IndicatorView, so I can have an overlay over multiple screens. Both the views replace my TabbedPage, but the IndicatorView needs to look like the TabbedPageBar. The only good page about styling an IndicatorView was this one: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/indicatorview.
Here is the page I have:
<StackLayout AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
Padding="0"
Spacing="0">
<IndicatorView x:Name="indicatorView">
<IndicatorView.IndicatorTemplate>
<DataTemplate>
<StackLayout HorizontalOptions="FillAndExpand">
<Frame Margin="10">
<Label/>
</Frame>
</StackLayout>
</DataTemplate>
</IndicatorView.IndicatorTemplate>
</IndicatorView>
<CarouselView ItemTemplate="{StaticResource templateSelector}"
IndicatorView="indicatorView">
<CarouselView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
</x:Array>
</CarouselView.ItemsSource>
</CarouselView>
</StackLayout>
Now how can I let the IndicatorView look like a TabbedPageBar?
I think the key point here is remove the Shadow and CornerRadius of Frame, then you can customize the layout in the Frame. Here is an example:
<IndicatorView x:Name="indicatorView" >
<IndicatorView.IndicatorTemplate>
<DataTemplate>
<StackLayout HorizontalOptions="FillAndExpand" Spacing="0">
<Frame HasShadow="False" CornerRadius="0">
<StackLayout Orientation="Vertical">
<Image Source="Images"/>
<Label Text="123" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</IndicatorView.IndicatorTemplate>
</IndicatorView>