Overflowing button in Xamarin Forms - layout

I've got a mockup with a screen I don't know how to implement properly:
I'm wondering how to position that Login button (and the "sign in with" block). Without "Login", it would be quite easy with a StackLayout. But this makes it less easy and I'm searching for a simple solution.
I presume it's feasible with an AbsoluteLayout with position calculations in the codebehind, but that makes the whole page more complicated than it looks.
The white block is a Frame that's used everywhere in the app. It's not specific to the login page, so I want to reuse it elsewhere.
How would you do that?

I think you can use a Grid... with 3 rows.
Rows 1 and 2 have the same height.
"Login data" (User/pwd...) occupy row 0 and 1
Button occupy row 2 and 2
For Example
<?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="fev_ventilazione_smartwatch.Pages.MyPageTest">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="8*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="4*" />
</Grid.ColumnDefinitions>
<Label Text="TEXT" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="3" BackgroundColor="Aqua"/>
<Button Text="BUTTON" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" BackgroundColor="Fuchsia"/>
</Grid>
</ContentPage.Content>
</ContentPage>
Produce

I presume it's feasible with an AbsoluteLayout with position
calculations in the codebehind, but that makes the whole page more
complicated than it looks.
Yes you are right. It is feasible with AbsoluteLayout. But its not as complicated as it seems.
Construct your basic elements first:
White container/StackLayout for login details
Login Button.
Facebook/Google buttons in a horizontal StackLayout.
"OR" Label
"Create An Account" Button
Put them in AbsoluteLayout and define their AbsoluteLayout.LayoutFlags as well as AbsoluteLayout.LayoutBounds.
Now key here is to understand that how Absolute Layout works?
You can find that out from this page: Absolute Layout
I have wrote some code to achieve something similar below. But make sure you learn it fully and understand everything before you can use it in your app:
<ContentPage.Content>
<ScrollView BackgroundColor="Silver">
<AbsoluteLayout Margin="30" >
<StackLayout BackgroundColor="White" HeightRequest="150" Spacing="20" Padding="10" VerticalOptions="FillAndExpand"
AbsoluteLayout.LayoutBounds="0,0,1,250" AbsoluteLayout.LayoutFlags="XProportional,YProportional,WidthProportional"
>
<Entry Text="Login" HeightRequest="30"/>
<Entry Text="Password" HeightRequest="30" IsPassword="true" />
<Label Text="FORGOT YOUR PASSOWORD?" HorizontalTextAlignment="End"/>
</StackLayout>
<Button
Text="LOGIN"
FontAttributes="Bold"
BackgroundColor="Maroon"
TextColor="White"
HeightRequest="70"
WidthRequest="70"
AbsoluteLayout.LayoutBounds=".5,215,70,70" AbsoluteLayout.LayoutFlags="XProportional" BorderRadius="35"
/>
<StackLayout
Orientation="Horizontal"
HorizontalOptions="EndAndExpand"
AbsoluteLayout.LayoutBounds="1,270,0.5,70" AbsoluteLayout.LayoutFlags="XProportional,WidthProportional"
>
<Button Text="Facebook"/>
<Button Text="Google"/>
</StackLayout>
<Label Text="OR" HorizontalTextAlignment="Center"
AbsoluteLayout.LayoutBounds="0.5,350,50,50"
AbsoluteLayout.LayoutFlags="XProportional"
/>
<Button
Text="CREATE AN ACCOUNT" Margin="15"
BackgroundColor="White" TextColor="Maroon"
BorderColor="Maroon" BorderWidth="1"
BorderRadius="0"
HorizontalOptions="FillAndExpand"
AbsoluteLayout.LayoutBounds="0.5,370,1,150"
AbsoluteLayout.LayoutFlags="XProportional,WidthProportional"
/>
</AbsoluteLayout>
</ScrollView>
</ContentPage.Content>
And here is the result:
NOTE: You can achieve the same look using RelativeLayout as well.
Hope this helps.

Related

CollectionView SelectionChanged method not triggering when tapping the item directly .NET MAUI

I'm creating a CollectionView in .net MAUI where i'm using Frame control inside the data template. As a result of that, when I tap directly on the item, the SelectionChanged method is not being triggered and will trigger only if I click on the frame border or outside of it. Below sample code and picture. Is this a bug in MAUI or I'm doing something wrong? I had the same setup in Xamarin and it was working with no issues.
XAML
<CollectionView x:Name="scheduleItemsCollection"
SelectionChanged="scheduleItemsCollection_SelectionChanged"
SelectionMode="Single"
>
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5" RowSpacing="0">
<Frame CornerRadius="40" BorderColor="Gray">
<StackLayout Spacing="0" BackgroundColor="White">
<Label Text="{Binding bookingDayArabic}" />
<Label Text="{Binding bookingDateD}" />
<StackLayout Orientation="Horizontal">
<Label Text="{Binding slotsAvailable}" HorizontalOptions="CenterAndExpand" />
<Label Text="عدد الطلبات:"/>
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Yes, it is the case as you said. Thanks for your support and feedback for maui.
I have created a new issue about this problem.
You can follow it up here: https://github.com/dotnet/maui/issues/9567.
Have a nice day.
This worked for me:
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="Section_Tapped"/>
</Frame.GestureRecognizers>

Xamarin ListView Issue

I am beginer on Xamarin. What did I do wrong here. I am trying to add Conext Menu to ListView and compiler is not happy with this.
<ListView x:Name="VehicleList">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell
ImageSource="152x152#1x.png"
Text="{Binding Title}"
Detail="{Binding SubTitle}"
TextColor="#f35e20"
DetailColor="#503026" />
<!-- adding this caused error
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="OnDelete" CommandParameter="{Binding .}"
Text="Archive"
IsDestructive="True" />
</ViewCell.ContextActions>
</ViewCell>
-->
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You are defining two viewcells in one data template. this is not possible!
You should create a DataTemplateSelector and declare the ViewCells in separate classes. Then you can make the selector choose a viewcell based on the logic implemented in the DataTemplateSelector. The xamarin documentation has a nice explanation: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/templates/data-templates/selector/

Show icon on SecondaryCommands (UWP)

I set the icons in my SecondaryCommand of CommandBar but aren't shown. Why?
<CommandBar RelativePanel.AlignRightWithPanel="True" RelativePanel.AlignVerticalCenterWithPanel="True" Margin="0">
<CommandBar.SecondaryCommands>
<AppBarButton Name="shareButton" Label="Condividi" x:Uid="condividi" Click="shareButton_Click" Icon="ReShare" />
<AppBarButton Name="contactButton" Icon="Contact" x:Uid="contatti" Label="Contatti" Click="contactButton_Click" />
</CommandBar.SecondaryCommands>
</CommandBar>
They are not shown because of the default AppBarButton template. You will need to modify it.
Just follow these steps:
Temporarily put an AppBarButton in the CommandBar.PrimaryCommands collection.
Right click the button in the designer and click on Edit Template > Edit a Copy...
In the dialog that opens enter a name for your style, e.g. MyAppBarButtonStyle
Set this style to your secondary buttons:
<CommandBar.SecondaryCommands>
<AppBarButton Name="shareButton" Label="Condividi" x:Uid="condividi" Icon="ReShare" Style="{StaticResource MyAppBarButtonStyle}" />
<AppBarButton Name="contactButton" Icon="Contact" x:Uid="contatti" Label="Contatti" Style="{StaticResource MyAppBarButtonStyle}" />
</CommandBar.SecondaryCommands>
Modify the style to your liking.
By default the following elemnt is used in the overflow menu:
<TextBlock x:Name="OverflowTextLabel" Foreground="{TemplateBinding Foreground}" FontSize="15" FontFamily="{TemplateBinding FontFamily}" HorizontalAlignment="Stretch" Margin="12,0,12,0" Padding="0,5,0,7" TextAlignment="Left" TextWrapping="NoWrap" Text="{TemplateBinding Label}" TextTrimming="Clip" Visibility="Collapsed" VerticalAlignment="Center"/>
You might want to replace it with something like that:
<StackPanel x:Name="OverflowContentRoot" Orientation="Horizontal" Visibility="Collapsed" MinHeight="{ThemeResource AppBarThemeCompactHeight}">
<ContentPresenter x:Name="OverflowContent" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" Height="20" Margin="0,14,0,4"/>
<TextBlock x:Name="OverflowTextLabel" Foreground="{TemplateBinding Foreground}" FontSize="15" FontFamily="{TemplateBinding FontFamily}" HorizontalAlignment="Stretch" Margin="12,0,12,0" Padding="0,5,0,7" TextAlignment="Left" TextWrapping="NoWrap" Text="{TemplateBinding Label}" TextTrimming="Clip" VerticalAlignment="Center"/>
</StackPanel>
You will also need to modify the overflow visual state to display your new template:
<VisualState x:Name="Overflow">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ContentRoot">
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="OverflowContentRoot">
<DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
And increase the button width:
<Setter Property="Width" Value="150"/>
Of course, you'll want to further modify the template to your liking, but this should at least get you going.
Damir's answer somehow put me on the right track and after spending a stupid amount of time on this, I eventually found out a solution that's simple.
Note that it may not suit everyone as the buttons don't get highlighted when hovering over with your mouse but it's the closest and easiest way I've figured out on how to do it on a UWP solution
First define a ControlTemplate in your Styles.xaml or your Page.Resources as such:
<ControlTemplate x:Key="SecondaryCommandTemplate" TargetType="AppBarButton">
<Grid x:Name="Root" Background="{TemplateBinding Background}">
<Grid x:Name="ContentRoot" HorizontalAlignment="Stretch" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter Grid.Column="0" VerticalContentAlignment="Center"
VerticalAlignment="Stretch" x:Name="Content"
AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Icon}"
Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch"
Height="20" Margin="7,0,7,0"/>
<TextBlock Grid.Column="1" VerticalAlignment="Center" x:Name="TextLabel"
Foreground="{TemplateBinding Foreground}" FontSize="12"
FontFamily="{TemplateBinding FontFamily}" TextAlignment="Left"
TextWrapping="Wrap" Text="{TemplateBinding Label}"/>
</Grid>
</Grid>
</ControlTemplate>
Then simply define the Template your SecondaryCommands:
<CommandBar.SecondaryCommands>
<AppBarButton Label="Settings"
Icon="Setting"
Command="{Binding CommandBarViewModel.SettingsCommand}"
Template="{StaticResource SecondaryCommandTemplate}"/>
<AppBarButton Label="Admin"
Icon="Admin"
Command="{Binding CommandBarViewModel.SettingsCommand}"
Template="{StaticResource SecondaryCommandTemplate}"/>
</CommandBar.SecondaryCommands>
It's a simple as that! What I don't get is that after following Damir's suggestion, and examining the XAML style that was generated for the button, I ended up removing all the visual states and I noticed that both my icon and text were displayed!! Why?? I don't understand why would Microsoft want to hide the icon in the SecondaryCommands and I'll be honest, I didn't spot the specific code that actually did it. Once I removed all the VisualStates, I noticed I was left with a template and then it was just a case of adding a grid and playing around with VerticalAlignment, HorizontalAlignment and 'Margin'.
Hope this helps!
Here's a much simpler, less elegant, way to do it. It works because most UWP icons are glyphs of the Segoe MDL2 Assets Font included in Windows.
Look up the Unicode point for the symbol you want from Microsoft's
Segoe MDL2 Assets
Guide
(eg. E702 for the Bluetooth icon, E72D for the Share icon).
Use something like UnicodeMap to
show that letter on screen. Don't worry that it looks like a blank
square, it'll work in your app.
Copy the character into your XAML as below, making sure to set the FontFamily of your AppBarButton to Segoe MDL2 Assets.
<CommandBar.SecondaryCommands>
<AppBarButton FontFamily="Segoe MDL2 Assets" Label=" Help"/>
<AppBarButton FontFamily="Segoe MDL2 Assets" Label=" Update database"/>
</CommandBar.SecondaryCommands>
And this is what you'll get.
I use this technique in an app that's localised to Russian and Chinese with no problems.
Well its pretty easier than this, use the reference microsoft.midiGmDls in your proyect and it's done.

The button is not visible

I have a UWP application, I have added a button but when I debug the application, I can't see the button. If I add a texblock or textBox I can see them, but not the button.
I have set IsEnabled to true and visibility to visible but I am not able to solve the problem.
Also I have tried to click in the place where it should be the button but nothing happens.
This happens when I debug in local machine and when I debug in a emulator of windows phone 10.
Thank you so much.
EDIT: the axml code
<Page
x:Class="SqliteEF7UWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SqliteEF7UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Transparent">
<Button x:Name="GetVideos" IsEnabled="True" Visibility="Visible" Background="Aquamarine" Content="Buscar Videos" HorizontalAlignment="Left" Margin="120,98,0,510" VerticalAlignment="Stretch" Click="button_Click"/>
<TextBlock x:Name="textBlock" Foreground="BlueViolet" HorizontalAlignment="Left" Margin="101,59,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="34" Width="132"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="213,59,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"/>
</Grid>
</Page>
The margin you set for the Button is too aggressive. The object is now "squeezed". For example set Margin to "120,98,0,200" (or simply "120,98") instead of "120,98,0,510" and it should be visible.
BTW using hardcoded margins to setup the user interface is probably not a good idea. Use for example the Grid with columns and rows instead of margins.

Androids RelativeLayout for Windows Phone

I'm currently trying to design a table for contact information including a column for icons like telephone, email or similar symbols and I want to align them with the text from the next column
icon | Telephone:
| +1212354567
icon | Email:
| x#y.com
Is there any Layout which can be compared in functionality to Androids RelativeLayout? I tried to work with the Grid Layout but this seems to be error prone and not exact enough. I don't want to divide my layout into columns and rows, instead I want to describe their position as it is used in RelativeLayout (toLeft, toRight, AlignParentBottom etc.).
The StackPanel can be compared to the LinearLayout, which I want to avoid as it is not suitable for my current design.
Is there any comparison between Windows Phone and Android Layouts on which I can orientate? This one is incomplete and does not give advise for the RelativeLayout.
I know you said you did not want to use a Grid but I feel that you have to in this case.
I would structure it with both a grid and stack panels though.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Image for first row item -->
<Image Grid.Column="0" Grid.Row="0" Source="icon-url" />
<!-- Container for the details of the first row item -->
<StackPanel Grid.Column="1" Grid.Row="0">
<TextBlock Text="Telephone:" />
<TextBlock Text="+1212354567" />
</StackPanel>
<!-- Image for second row item -->
<Image Grid.Column="0" Grid.Row="1" Source="icon-url" />
<!-- Container for the details of the second row item -->
<StackPanel Grid.Column="1" Grid.Row="1">
<TextBlock Text="Email:" />
<TextBlock Text="x#y.com" />
</StackPanel>
<!-- Just add rows to the grid to continue the list -->
</Grid>
There is no panel that compares, but someone that was adventurous could create one. There are many articles on how to do this, but here's one for reference. http://www.switchonthecode.com/tutorials/wpf-tutorial-creating-a-custom-panel-control
That said, there's no reason not to use Grid for what you're trying to do. It's not "error prone" or "not exact enough". SharedSizeGroup should become your friend here, though.

Resources