StackLayout stays above controls, but allows tap on buttons and entries in .Net MAUI - .net-6.0

I have a StackLayout inside an AbsoluteLayout with some entries and a button, and the StackLayout has the LayoutBounds equal to "0,0,1,1" and the LayoutFlags equal to "All".
When I tap on the button, I show a Grid that has the same AbsoluteLayout properties described above, so that this Grid positions itself above the previous StackLayout, hiding all controls.
This Grid has a BoxView with a Gray color with some opacity, and an ActivityIndicator running.
Everything works as expected, except the fact that I still can tap on the entries (showing the virtual keyboard) and the button.
I know that this Grid is above the StackLayout with the controls, but why can I still tap on them ? I have the same solution in Xamarin Forms, and it works as expected, the controls have their events inhibited, since they are in a layer beneath.
Here is some sample code. For testing purposes, the Grid is already visible, but the intent is only making it visible after the tap on the button.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PdC.Views.SamplePage"
Title="SamplePage">
<AbsoluteLayout>
<VerticalStackLayout
BackgroundColor="White"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand"
Padding="0,50,0,0"
Spacing="50">
<Entry
WidthRequest="200"
BackgroundColor="Yellow"
TextColor="Black"
Text="sample text on first entry" />
<Entry
WidthRequest="200"
TextColor="Black"
BackgroundColor="Yellow"
Text="sample text on second entry" />
<Button
Text="tap on me"
WidthRequest="200" />
</VerticalStackLayout>
<Grid
IsVisible="True"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<BoxView
ZIndex="9"
Grid.RowSpan="2"
BackgroundColor="Red"
VerticalOptions="FillAndExpand"
Opacity="0.5" />
<Frame
BackgroundColor="White"
Grid.Row="1">
<VerticalStackLayout
VerticalOptions="FillAndExpand">
<ActivityIndicator
IsRunning="True"
HorizontalOptions="Center"
Color="Red"/>
<Label
TextColor="Black"
Text="Please wait ..."
HorizontalOptions="Center"/>
</VerticalStackLayout>
</Frame>
</Grid>
</AbsoluteLayout>
</ContentPage>
As you can see, the entries and the button have their background color red with some transparency, meaning that the grid is above the stacklayout, but I still can tap on the entries (and the button) as the screenshots show.
Before tapping on the entry
After tapping the entry

Yes, it is the case as you said.
As a test, I replaced VerticalStackLayout with StackLayout and changed the property of BoxView from BackgroundColor="Red" to BackgroundColor="Transparent" .
Then I tested on xamarin forms, there was no such problem. This should be an issue in maui.
And I have created a new issue about this problem, you can follow it up here: https://github.com/dotnet/maui/issues/9514 .
Thanks for your feedback. Have a nice day.

Related

Xamarin Forms: Expand Button size in a Grid for larger Accessible Text

I am creating a search form with an Entry and a Button at the top. I have it all laid out well when the text is a normal size. I have implemented scaling fonts for accessibility, and now when the font is at the second to largest size the font is too big for the button and it cuts off the text.
Here is my current code. I don't require using a grid, it's just the only way I could get the entry control to fill out all of the extra space that the button isn't using. The width and height requests on the controls is the only way I could get them to look well on normal text sizing
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:BorderedEntry Grid.Column="0" x:Name="queryEntry" Text="{Binding QueryString}" FontSize="{DynamicResource StandardLabelFontSize}"
BorderColor="{AppThemeBinding Light={StaticResource PrimaryColorLight}, Dark={StaticResource PrimaryColorDark}}" CompletedCommand="{Binding FindTextCommand}"
Placeholder="Search string" ReturnType="Search" ClearButtonVisibility="WhileEditing"
VerticalOptions="CenterAndExpand" HeightRequest="{OnPlatform Android=50, iOS=35}" Margin="10,15,5,5"
IsClippedToBounds="True" CornerRadius="5" AutomationId="TextSearchEntry" />
<Button Grid.Column="1" Text="Find" Command="{Binding FindTextCommand}" Margin="0,10,10,0" WidthRequest="80"
HeightRequest="35" IsEnabled="{Binding QueryString, Converter={StaticResource NonEmptyStringValue}}"
FontSize="{DynamicResource StandardLabelFontSize}" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</Grid>
Here is what it looks like on normal text sizing:
Here is what it looks like on the third to largest text size:
Here is what happens once I go to the second to, and largest text size:
And here is ideally what I would like it to look like at a minimum visual. I got this by setting the buttons width request to 100 instead of 80 (I ideally don't want this value as it doesn't look good on small text size):
The only solution I have came up with is keep track of what the text scaling is, and once it goes above 1.5, then I can increase the WidthRequest on the button control. Ideally I would just like the button to adjust to the width of the text.
EDIT 1:
I tried Jason's solution with this code here:
<StackLayout Orientation="Horizontal">
<controls:BorderedEntry Text="{Binding QueryString}" FontSize="{DynamicResource StandardLabelFontSize}"
BorderColor="{AppThemeBinding Light={StaticResource PrimaryColorLight}, Dark={StaticResource PrimaryColorDark}}" CompletedCommand="{Binding FindTextCommand}"
Placeholder="Search string" ReturnType="Search" ClearButtonVisibility="WhileEditing"
VerticalOptions="CenterAndExpand" HeightRequest="{OnPlatform Android=50, iOS=40}" Margin="10,15,5,5"
HorizontalOptions="FillAndExpand"
IsClippedToBounds="True" CornerRadius="5" AutomationId="TextSearchEntry" />
<Button Text="Find" Command="{Binding FindTextCommand}" Margin="0,10,10,0"
IsEnabled="{Binding QueryString, Converter={StaticResource NonEmptyStringValue}}"
FontSize="{DynamicResource StandardLabelFontSize}" VerticalOptions="Center"
Padding="20,0,20,0"/>
</StackLayout>
I had to leave the HeightRequest on the Entry else the entry would be a smaller height. Without the Padding on the Button it showed like so:
Adding the padding added some space to the button (I tried this instead of the WidthRequest):
So now it looks good on normal text, however once I start cranking up the text size in accessibility, it looks good on the 3rd to largest size (same as my original solution above):
But once I move it to the top two it starts pushing the button off the screen to the right:
Then I had the idea to go back to using the Grid and using Padding instead of the WidthRequest on the Button, and it displays correctly:
this works for me. As I change the FontSize of the button, the entry will adjust to accomodate
<StackLayout Padding="10,100,10,0" HeightRequest="50" Orientation="Horizontal" BackgroundColor="LightBlue">
<Entry HorizontalOptions="FillAndExpand" Placeholder="Search" />
<Button FontSize="80" Text="Find" />
</StackLayout>
After trying out Jason's suggested solution it still did not layout properly at the largest text accessibility settings (see my edits above in the original post). I tried putting a Padding="20,0,20,0" on the Button and removed the WidthRequest to add spacing around the Find text in the normal text size case and that seems to have allowed the Grid to auto-layout the width I also removed the HeightRequests on both controls. I don't like how the Find button looks as it is larger than the entry. Here's the final xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<controls:BorderedEntry Grid.Column="0" Text="{Binding QueryString}" FontSize="{DynamicResource StandardLabelFontSize}"
BorderColor="{AppThemeBinding Light={StaticResource PrimaryColorLight}, Dark={StaticResource PrimaryColorDark}}" CompletedCommand="{Binding FindTextCommand}"
Placeholder="Search string" ReturnType="Search" ClearButtonVisibility="WhileEditing"
VerticalOptions="CenterAndExpand" Margin="10,15,5,5"
IsClippedToBounds="True" CornerRadius="5" AutomationId="TextSearchEntry" />
<Button Grid.Column="1" Text="Find" Command="{Binding FindTextCommand}" Margin="0,10,10,0"
IsEnabled="{Binding QueryString, Converter={StaticResource NonEmptyStringValue}}"
FontSize="{DynamicResource StandardLabelFontSize}" VerticalOptions="CenterAndExpand"
Padding="20,0,20,0"/>
</Grid>
With these visuals on normal text (iOS / Android):
And these visuals on the largest text size (iOS / Android):
To fix the issue where the Find button is taller than I really want it to be on the normal text, I added conditional Binding depending on what the font scaling is:
private void SetButtonBinding()
{
if (App.Current.CurrentFontScale < ScaleFontThreshold)
{
findButton.SetBinding(Button.HeightRequestProperty, nameof(FindViewModel.ButtonHeightRequest));
}
else
{
findButton.RemoveBinding(Button.HeightRequestProperty);
}
}
Which achieves these final visuals:
I wish there was a way to do this all through Xaml, but I can't seem to find the settings.

Can I have two tab bars in Xamarin forms?

Good day fellow code ninjas!!!
Using a '< TabbedPage/ >' in Xamarin forms I can easily create a tab bar at the top of my page. I would however like to have two tab bars instead of one. For example, 3 tab buttons in the first tab bar row and another 3 in the second row and the user being able to navigate between all 6 pages.
Does anyone perhaps know if this is possible in Xamarin forms and/or if there is any documentation that might assist.
You could use the TabView from the Xamarin Community Toolkit in addition to your TabbedPage 😉. Here's how it works:
<Grid>
<xct:TabView>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent1" />
</Grid>
</xct:TabViewItem>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent2" />
</Grid>
</xct:TabViewItem>
</xct:TabView>
</Grid>
If you put a TabView in each of your TabBar contents you will be able to get the result you want.
In your case, it would be something like this:
<ContentPage Title="Tab 1">
<xct:TabView>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent1" />
</Grid>
</xct:TabViewItem>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent2" />
</Grid>
</xct:TabViewItem>
</xct:TabView>
</ContentPage>
<ContentPage Title="Tab 2">
<xct:TabView>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent1" />
</Grid>
</xct:TabViewItem>
<xct:TabViewItem>
<Grid>
<Label
HorizontalOptions="Center"
VerticalOptions="Center"
Text="TabContent2" />
</Grid>
</xct:TabViewItem>
</xct:TabView>
</ContentPage>
If you want to see more about TabViews, there is a great article posted by Gerald Versluis, that explains it perfectly: https://devblogs.microsoft.com/xamarin/xamarin-community-toolkit-tabview/
Give it a try with James Montemagno youtube channel
EDIT
here is the official github link for the library used by that video
https://github.com/roubachof/Sharpnado.Tabs

Xamarin forms listview - show images full widh, auto height

I have a listview in Xamarin Forms and I have a requirement to maintain aspect ratio but also this:
When an image is taller than it is wide, show the image flush to the left and right with no margins, have the height be auto
When an image is wider than it is tall, the requirement is the same, but this works. In the screenshot it shows how images currently render when they're taller than wide. Changing the aspect property breaks the condition when it is wider than tall. When I copy this template into a blank page, the image displays fine. I think the issue is being able to set the height of each row in the listview to auto. It may not be the issue though. I'm using a SyncFusion listview for Xamarin
Here is the code for the item template of the listview:
<DataTemplate>
<ViewCell>
<StackLayout Margin="0,10,0,10" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<!-- Card Header -->
<!-- Truncated for brevity -->
</Grid>
<StackLayout Grid.Row="1">
<!-- Card title -->
<!-- Truncated for brevity -->
</StackLayout>
<!-- Card Body -->
<StackLayout BindingContextChanged="PostImageStackLayout_BindingContextChanged">
<Grid Grid.Row="2" x:Name="postImageStackLayout" Margin="0,15,0,10">
<!-- Card article image -->
<ffimageloading:CachedImage Grid.Row="0" x:Name="postImage" CacheDuration="1" HeightRequest="300"
Source="{Binding MainIMageURL}" BindingContextChanged="PostImage_BindingContextChanged"
VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"
Margin="0,10,0,10" FadeAnimationEnabled="True" Aspect="AspectFit" >
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="PostImageTapped" CommandParameter="{Binding }"/>
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
</Grid>
</StackLayout>
<!--Likes and comment count-->
<!-- Truncated for brevity -->
Don't put fix height on Grid Row where it have the image element. You can use the "auto" value.
<RowDefinition Height="auto"/>
and change the Aspect to
AspectFill
I use the collectionview from the latest Xamarin.Forms 4.3. Here is my sample code
xaml
<ContentView.Content>
<StackLayout>
<CollectionView x:Name="ImagesCollectionView">
<CollectionView.ItemsLayout>
<ListItemsLayout ItemSpacing="20">
<x:Arguments>
<ItemsLayoutOrientation>Vertical</ItemsLayoutOrientation>
</x:Arguments>
</ListItemsLayout>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<ffimageloading:CachedImage
HorizontalOptions="FillAndExpand"
Source="{Binding .}"
Aspect="AspectFill"
LoadingPlaceholder="noimg.png"/>
<Label Text="label"
TextColor="Gray"
Opacity="0.8"
Margin="12,0,0,0"
HorizontalOptions="Start"
FontSize="Small"/>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentView.Content>
c#
public MySecondView()
{
InitializeComponent();
ImagesCollectionView.ItemsSource = new List<string>()
{
"http://insidetema.com/wp-content/uploads/2018/05/170717100550_1_900x600.jpg"
,"https://informationng.com/wp-content/uploads/2014/03/bigstock_Happy_Business_People_With_Han_4049346.jpg"
,"http://www.blt.co.uk/wp-content/uploads/2018/03/Happy-Places.jpg"
};
}
Output
You can set the HeightRequest and WidthRequest of your image to -1 (then it'll fit all the space available)

Disable Xamarin Form and Show Activity Indicator

I have a Xamarin Form which is using Scroll View.
I am trying to show a Activity Indicator at the top as I have a ListView in the middle.
But when the user scrolls down the loading is not shown.
So, I need help in disabling the page and showing loading at some z-index as in a popup.
If you want to have an overlay while the screen is loading you can do this.
<Grid>
<ScrollView>
<!-- Insert your page content in here -->
</ScrollView>
<ContentView IsVisible="false" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ActivityIndicator IsRunning="false" />
</ContentView>
</Grid>
When you set your ContentView to IsVisible="true" it will then overlay on top of your page. You can set the background color and opacity on the ContentView if needed to provide a grey out effect.
Or you can use a similar method and have
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ActivityIndicator Grid.Row="0" />
<ScrollView Grid.Row="1">
</ScrollView>
</Grid>
In this way you will have the activity indicator above the scroll view at all times and allow the user to still scroll.
I am new to the Xamarin but you do as below.
<Grid IsEnabled="{Binding IsBusy,Converter={converters:InverseBoolConverter}}" >
...
<ActivityIndicator
Color="{StaticResource LightGreenColor}"
IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
VerticalOptions="Center"
HorizontalOptions="Center">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS, Android" Value="100" />
<On Platform="UWP, WinRT, WinPhone" Value="400" />
</OnPlatform>
</ActivityIndicator.WidthRequest>
</ActivityIndicator>
</Grid>

Xamarin.Forms - How To Make Left Sidebar Swipe Out and Main Page Slide With It

I'm looking to create a specific animation where you start with a collapsed sidebar (still visible, but skinny) and main page content:
and when you pull out the left sidebar, the sidebar expands, and the main content moves with it (so that the right part of the main content slides out of view):
Also, note that the content in the sidebar doesn't move (though there is additional content that appears (button on the bottom)), but rather the width of the sidebar container just expands. Finally, I would like it to slide with my finger, not just be a static animation.
How do I accomplish this in Xamarin.Forms? (Is it possible?)
You can found it in Telerik Xamarin Forms sample (SlideDrawer -> Transitions/Location)
Sign in your account (telerik.com), I thinks it's free ..
Playing with the Xamarin Studio XAML Preview:
It is a matter of binding your expand event to WidthRequest in the first "column" to resize it and push the "right" side over. Depending upon the control settings in the first column, they will either expand to fill the new "column" width or stay a fixed size...
Note: Personally I would do this using ConstraintExpressions in order to make the design truly dynamic and adaptive to orientation changes, different screen sizes, etc...
<StackLayout RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.25}"
RelativeLayout.YConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.75}"
</StackLayout>
Example XAML from preview image above:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="OpenDrawer.TestLayoutPreview">
<ContentPage.Content>
<StackLayout BackgroundColor="Blue" Orientation="Horizontal">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Vertical" BackgroundColor="Maroon" HorizontalOptions="Start" VerticalOptions="FillAndExpand" MinimumWidthRequest="100" WidthRequest="100">
<Button Text="Left 1" BackgroundColor="Aqua"></Button>
<Button Text="Left 2" BackgroundColor="Aqua"></Button>
<Button Text="Left 3" BackgroundColor="Aqua"></Button>
</StackLayout>
<StackLayout Orientation="Vertical" VerticalOptions="End">
<Button Text="Left Bottom" BackgroundColor="Lime"></Button>
</StackLayout>
</StackLayout>
<StackLayout Orientation="Vertical" BackgroundColor="Red" HorizontalOptions="FillAndExpand">
<Label Text="Right" BackgroundColor="Aqua"></Label>
<ScrollView>
<WebView Source="https://xamarin.com" WidthRequest="1000" HeightRequest="1000" ></WebView>
</ScrollView>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>

Resources