I'm currently trying to use a static resource with an extension for my entry's FontSize property. I have this code piece of code:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="PROJECT.Sources.Pages.Extras.EditProfilePage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:control="clr-namespace:PROJECT.Sources.Controls;assembly=PROJECT"
xmlns:extension="clr-namespace:PROJECT.Sources.Extensions;assembly=PROJECT"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="NL_BlueNight">#0E1728</Color>
<Color x:Key="NL_OrangeBeer">#E87E07</Color>
<Color x:Key="NL_OrangeSky">#BD4327</Color>
<Color x:Key="NL_White">#ECECEC</Color>
<sys:Double x:Key="EntryFontSize">20</sys:Double>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<AbsoluteLayout BackgroundColor="{x:StaticResource NL_BlueNight}">
<AbsoluteLayout
Margin="{Binding LayoutThicknessAdapter}"
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Black">
<control:Gif
AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.9"
AbsoluteLayout.LayoutFlags="All"
GifSource="Gifs/LoginBackground.gif" />
<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent" />
</AbsoluteLayout>
<AbsoluteLayout
Margin="{Binding LayoutThicknessAdapter}"
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="{StaticResource NL_BlueNight}"
Opacity="0.8">
<ScrollView AbsoluteLayout.LayoutBounds="0.5, 0, 1, 0.9" AbsoluteLayout.LayoutFlags="All">
<StackLayout
HorizontalOptions="Fill"
Orientation="Vertical"
Spacing="15"
VerticalOptions="CenterAndExpand">
<BoxView BackgroundColor="Transparent" HeightRequest="{Binding SeparatorHeight}" />
<control:CustomImageCircle
x:Name="UserProfileImageButton"
HeightRequest="{Binding PictureHeightWidth}"
HorizontalOptions="Center"
Source="{Binding CurrentUser.ImageProfile}"
VerticalOptions="Center"
WidthRequest="{Binding PictureHeightWidth}" />
<Image
HeightRequest="{Binding SeparatorHeight}"
HorizontalOptions="Center"
Source="{extension:ImageSource LogoPROJECT.png}" />
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
Placeholder="pseudo"
PlaceholderColor="Gray"
Text="{Binding CurrentUser.Pseudo}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
Placeholder="email"
PlaceholderColor="Gray"
Text="{Binding CurrentUser.Email}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
Placeholder="firstname"
PlaceholderColor="Gray"
Text="{Binding CurrentUser.Firstname}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
Placeholder="lastname"
PlaceholderColor="Gray"
Text="{Binding CurrentUser.Lastname}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
Keyboard="Telephone"
Placeholder="phone number"
PlaceholderColor="Gray"
Text="{Binding CurrentUser.Number}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
IsPassword="True"
Placeholder="password"
PlaceholderColor="Gray"
Text="{Binding PasswordOne}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
<AbsoluteLayout HeightRequest="{Binding EntryHeight}" WidthRequest="{Binding EntryWidth}">
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="{extention:FontSize StaticResourceKey=EntryFontSize}}"
HasBorder="false"
IsPassword="True"
Placeholder="password (retype)"
PlaceholderColor="Gray"
Text="{Binding PasswordTwo}"
TextColor="White"
XAlign="Center" />
<!--<BoxView
AbsoluteLayout.LayoutBounds="0.5, 0.7, 0.8, 1"
AbsoluteLayout.LayoutFlags="XProportional, YProportional, WidthProportional"
BackgroundColor="{StaticResource NL_OrangeBeer}" />-->
</AbsoluteLayout>
</StackLayout>
</ScrollView>
<AbsoluteLayout
AbsoluteLayout.LayoutBounds="0.5,1,1,0.1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="{StaticResource NL_OrangeBeer}">
<control:CustomLabel
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
FontFamily="{extension:FontFamily Roboto_Light}"
FontSize="35"
HorizontalTextAlignment="Center"
Text="Save and Return"
TextColor="White"
VerticalTextAlignment="Center" />
<control:CustomButton
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
BorderColor="Transparent"
Clicked="OnSaveClicked" />
</AbsoluteLayout>
<AbsoluteLayout
AbsoluteLayout.LayoutBounds="0, 0, 0.1, 0.1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
IsVisible="{Binding IsReturnVisible}">
<control:CustomImage
AbsoluteLayout.LayoutBounds="0.5, 0.5, 0.8, 0.8"
AbsoluteLayout.LayoutFlags="All"
Aspect="AspectFit"
Source="{extension:ImageSource cross.png}" />
<control:CustomButton
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Transparent"
BorderColor="Transparent"
Clicked="OnReturnClicked" />
</AbsoluteLayout>
</AbsoluteLayout>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
Where extension:FontSize is coming from :
[ContentProperty("FontSize")]
public class FontSizeExtension : IMarkupExtension
{
public double FontSize { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
return Services.Sizing.FontSizeAdapter(FontSize);
}
}
Sizing.cs
public class Sizing
{
public static double FontSizeAdapter(double fontSize)
{
switch (Device.RuntimePlatform)
{
case "Android":
return (fontSize / 2);
case "iOS":
return fontSize;
case "Windows":
case "WinPhone":
return fontSize;
default:
return fontSize;
}
}
}
However, when I do FontSize="{extention:FontSize {x:StaticResource EntryFontSize}}" it throws an exception that says that the value cannot be null.. How can I use the both at the same time? I mean the x:StaticResource and the Extension
Thank !
Edit - 08/18
1. Ensure prefix is correctly defined and used
Make sure to check the namespace provided for prefix is correct for your markup extension, and that there is no spelling mistake while specifying the prefix. This should resolve the 'Value cannot be null' error.
2. Specify property name while using nested markup-extensions
The property-name of extension needs to be specified while using nested markup-extension. Otherwise, my tests show, it is treated as a string value and assigned to default content property. This should resolve the error 'Input string was not in a correct format'.
Solution-1: Specify property-name
<control:CustomEntry
AbsoluteLayout.LayoutBounds="0.5, 0.5, 1, 1"
AbsoluteLayout.Flags="All"
...
FontSize="{extension:FontSize FontSize={x:StaticResource EntryFontSize}}"
.../>
Solution-2: You can simplify this further by adding a StaticResourceKey property in markup extension:
[ContentProperty("FontSize")]
public class FontSizeExtension : IMarkupExtension
{
public double FontSize { get; set; }
public string StaticResourceKey { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
throw new ArgumentNullException(nameof(serviceProvider));
if (StaticResourceKey != null)
{
var staticResourceExtension = new StaticResourceExtension { Key = StaticResourceKey };
FontSize = (double)staticResourceExtension.ProvideValue(serviceProvider);
}
return Services.Sizing.FontSizeAdapter(FontSize);
}
}
and usage can be:
...
FontSize="{extension:FontSize StaticResourceKey=EntryFontSize}}"
...
Related
I need to create a ScrollView in this layout but the problem is that my control occupies the entire screen and I don't know how to make it occupy only the size it has. This is the functionality of the control
I need it not to fill the entire screen and only its own size to be able to add more things to the layout
This is the XAML of my control:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="ControlProject.CustomControl"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="CustomView">
<ContentView.Content>
<AbsoluteLayout>
<!-- ================This is the entry that must be in the bottom================ -->
<StackLayout
x:Name="STACK"
AbsoluteLayout.LayoutBounds="0,1,1,0.07"
AbsoluteLayout.LayoutFlags="All"
Orientation="Horizontal">
<Frame
Margin="0,0,0,2"
Padding="0,0,0,0"
BackgroundColor="{Binding Source={x:Reference CustomView}, Path=FrameColor}"
BorderColor="{Binding Source={x:Reference CustomView}, Path=BorderColor}"
CornerRadius="{Binding Source={x:Reference CustomView}, Path=CornerRadius}"
HasShadow="False"
HorizontalOptions="FillAndExpand">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ImageButton
Grid.Column="0"
Margin="5,0,0,0"
BackgroundColor="Transparent"
Clicked="Open"
HeightRequest="25"
HorizontalOptions="Start"
Source="{Binding Source={x:Reference CustomView}, Path=LeftSideIcon}" />
<Entry
x:Name="EntryControl"
Grid.Column="1"
Margin="0,0,55,0"
HeightRequest="25"
HorizontalOptions="FillAndExpand"
Keyboard="Chat"
Placeholder="{Binding Source={x:Reference CustomView}, Path=Placeholder}"
Text="{Binding EntryText}"
TextColor="{Binding Source={x:Reference CustomView}, Path=EntryTextColor}" />
<ImageButton
Grid.Column="1"
Margin="0,0,40,0"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=DeleteMsgCommand}"
HeightRequest="25"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=DeleteMessageIcon}" />
<ImageButton
Grid.Column="1"
Margin="0,0,10,0"
Padding="1"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=InsertImgCommand}"
HeightRequest="25"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=InsertImgIcon}" />
</Grid>
</Frame>
<ImageButton
Margin="0,0,5,2"
Padding="15,0,10,0"
BackgroundColor="{Binding Source={x:Reference CustomView}, Path=SendBtnColor}"
Command="{Binding Source={x:Reference CustomView}, Path=SendMsgCommand}"
CornerRadius="30"
HeightRequest="45"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=RightSideIcon}"
WidthRequest="45" />
</StackLayout>
<!-- ================This is what it moves up================ -->
<StackLayout
x:Name="frameemojis"
AbsoluteLayout.LayoutBounds="0,1,1,0.43"
AbsoluteLayout.LayoutFlags="All"
TranslationY="{Binding Height, Source={x:Reference frameemojis}}">
<Frame>
<CollectionView
Margin="-10,-15,-10,-10"
HeightRequest="270"
ItemsSource="{Binding Source={x:Reference CustomView}, Path=EmojiItemSource}"
VerticalScrollBarVisibility="Never">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal" Span="5" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ImageButton
Padding="5"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=EmojiTappedCommand}"
CommandParameter="{Binding EmojiMethodCommand}"
HeightRequest="44"
Source="{Binding EmojiSource}"
WidthRequest="44" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Frame>
<!-- ============== -->
</StackLayout>
</AbsoluteLayout>
</ContentView.Content>
</ContentView>
MainPage.xaml (this is where I want to add the ScrollView):
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="App24.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:fav="clr-namespace:ControlProject;assembly=ControlProject">
<AbsoluteLayout>
<!-- This is where I want to add the scrollview -->
<StackLayout
AbsoluteLayout.LayoutBounds="0,1,1,1"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="#4DFF0000">
<fav:CustomControl
x:Name="entrycontrol"
BorderColor="{Binding EntryBorderColor}"
CornerRadius="{Binding EntryRadius}"
DeleteMessageIcon="crossblack.png"
DeleteMsgCommand="{Binding DeleteMsgCommand}"
EmojiItemSource="{Binding EmojiList}"
EmojiTappedCommand="{Binding EmojiTappedCommand}"
EntryTextColor="{Binding TextColor}"
FrameColor="{Binding EntryBGColor}"
InsertImgCommand="{Binding InsertImgCommand}"
InsertImgIcon="insertimage.png"
LeftSideIcon="icon.png"
Placeholder="Escribddame"
RightSideIcon="send.png"
SendBtnColor="{Binding SendBtnColor}"
SendMsgCommand="{Binding SendMsgCommand}" />
</StackLayout>
</AbsoluteLayout>
</ContentPage>
[EDITED]
Method on code behind control:
bool isShow;
const double layoutPropHeightMax = 0.45;
const double layoutPropHeightMin = 0.06;
private void Button_Clicked(object sender, EventArgs e)
{
if (!isShow)
{
//show the keyboard
Device.BeginInvokeOnMainThread(async () =>
{
var height = layoutPropHeightMin;
while (height < layoutPropHeightMax)
{
await Task.Delay(1);
height += 0.04;
AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
}
});
}
else
{
// hide the keyboard
Device.BeginInvokeOnMainThread(async () =>
{
var height = layoutPropHeightMax;
while (height > layoutPropHeightMin)
{
await Task.Delay(1);
height -= 0.04;
AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
}
});
}
isShow = !isShow;
}
Control XAML:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
x:Class="ControlProject.CustomControl"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="CustomView">
<AbsoluteLayout AbsoluteLayout.LayoutBounds="0,1,1,1" BackgroundColor="White">
<StackLayout
x:Name="bottomBar"
AbsoluteLayout.LayoutBounds="0.5,1,1.0,0.07"
AbsoluteLayout.LayoutFlags="All"
BackgroundColor="Olive">
<StackLayout
x:Name="STACK"
AbsoluteLayout.LayoutBounds="0,1,1,0.07"
AbsoluteLayout.LayoutFlags="All"
Orientation="Horizontal">
<Frame
Margin="0,0,0,2"
Padding="0,0,0,0"
BackgroundColor="{Binding Source={x:Reference CustomView}, Path=FrameColor}"
BorderColor="{Binding Source={x:Reference CustomView}, Path=BorderColor}"
CornerRadius="{Binding Source={x:Reference CustomView}, Path=CornerRadius}"
HasShadow="False"
HorizontalOptions="FillAndExpand">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ImageButton
Grid.Column="0"
Margin="5,0,0,0"
BackgroundColor="Transparent"
Clicked="Button_Clicked"
HeightRequest="25"
Source="{Binding Source={x:Reference CustomView}, Path=LeftSideIcon}" />
<Entry
x:Name="EntryControl"
Grid.Column="1"
Margin="0,0,55,0"
HeightRequest="25"
HorizontalOptions="FillAndExpand"
Keyboard="Chat"
Placeholder="{Binding Source={x:Reference CustomView}, Path=Placeholder}"
Text="{Binding EntryText}"
TextColor="{Binding Source={x:Reference CustomView}, Path=EntryTextColor}" />
<ImageButton
Grid.Column="1"
Margin="0,0,40,0"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=DeleteMsgCommand}"
HeightRequest="25"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=DeleteMessageIcon}" />
<ImageButton
Grid.Column="1"
Margin="0,0,10,0"
Padding="1"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=InsertImgCommand}"
HeightRequest="25"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=InsertImgIcon}" />
</Grid>
</Frame>
<ImageButton
Margin="0,0,5,2"
Padding="15,0,10,0"
BackgroundColor="{Binding Source={x:Reference CustomView}, Path=SendBtnColor}"
Command="{Binding Source={x:Reference CustomView}, Path=SendMsgCommand}"
CornerRadius="30"
HeightRequest="45"
HorizontalOptions="End"
Source="{Binding Source={x:Reference CustomView}, Path=RightSideIcon}"
WidthRequest="45" />
</StackLayout>
<!-- ================This is what it moves up================ -->
<StackLayout
x:Name="frameemojis"
AbsoluteLayout.LayoutBounds="0,1,1,0.43"
AbsoluteLayout.LayoutFlags="All"
TranslationY="{Binding Height, Source={x:Reference frameemojis}}">
<Frame>
<CollectionView
Margin="-10,-15,-10,-10"
HeightRequest="270"
ItemsSource="{Binding Source={x:Reference CustomView}, Path=EmojiItemSource}"
VerticalScrollBarVisibility="Never">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal" Span="5" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ImageButton
Padding="5"
BackgroundColor="Transparent"
Command="{Binding Source={x:Reference CustomView}, Path=EmojiTappedCommand}"
CommandParameter="{Binding EmojiMethodCommand}"
HeightRequest="44"
Source="{Binding EmojiSource}"
WidthRequest="44" />
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Frame>
<!-- ============== -->
</StackLayout>
</StackLayout>
</AbsoluteLayout>
</ContentView>
This is how I want to make it
In the ContentPage because you set the height of Stacklayout as the whole screen
AbsoluteLayout.LayoutBounds="0,1,1,1"
So it will be an expected result .
Actually , in your case you could implement the effect without using ScrollView .
in ContentPage
<AbsoluteLayout BackgroundColor="White" AbsoluteLayout.LayoutBounds="0,1,1,1">
<!-- -->
<Button Clicked="Button_Clicked" Text="Test" AbsoluteLayout.LayoutBounds="0.5,0.3,0.2,0.05" AbsoluteLayout.LayoutFlags="All" />
<StackLayout x:Name="bottomBar" BackgroundColor="Olive" AbsoluteLayout.LayoutBounds="0.5,1.0,1.0,0.04" AbsoluteLayout.LayoutFlags="All">
<!-- put the content of emoji keyboard and entry here -->
</StackLayout>
</AbsoluteLayout>
In Code behind
bool isShow;
const double layoutPropHeightMax = 0.45;
const double layoutPropHeightMin = 0.06;
//you could set the height here as you want
private void Button_Clicked(object sender, EventArgs e)
{
if(!isShow)
{
//show the keyboard
Device.BeginInvokeOnMainThread(async () =>
{
var height = layoutPropHeightMin;
while (height < layoutPropHeightMax)
{
await Task.Delay(1);
height += 0.04;
AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0,1.0, height));
}
});
}
else
{
// hide the keyboard
Device.BeginInvokeOnMainThread(async () =>
{
var height = layoutPropHeightMax;
while (height > layoutPropHeightMin)
{
await Task.Delay(1);
height -= 0.04;
AbsoluteLayout.SetLayoutBounds(bottomBar, new Rectangle(0.5, 1.0, 1.0, height));
}
});
}
isShow = !isShow;
}
And in Custom Control let the Entry and Keyboard fill the whole StackLayout .
I have this Xamarin XAML which have a background image with header text and 3 button overlay at the bottom. Second how do I remove the extra margin between the 3 buttons?
<AbsoluteLayout>
<Image Source="Flower.jfif" Aspect="AspectFill" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" />
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,0,1,0.1" AbsoluteLayout.LayoutFlags="All" Margin="0,20">
<StackLayout BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<Label Text="Relax" TextColor="White" FontSize="30" HorizontalOptions="Center" />
</StackLayout>
</AbsoluteLayout>
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,1,1,0.1" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#66000000">
<StackLayout Orientation="Horizontal" BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<Button Text="Profile" BackgroundColor="Transparent" TextColor="White" HorizontalOptions="FillAndExpand" />
<Button Text="Meditate" BackgroundColor="Transparent" TextColor="White" HorizontalOptions="FillAndExpand" />
<Button Text="Theme" BackgroundColor="Transparent" TextColor="White" HorizontalOptions="FillAndExpand" />
</StackLayout>
</AbsoluteLayout>
</AbsoluteLayout>
XAML Header text missing when phone preview orientation change to
horizontal
This is caused by the margin(Margin="0,20") you set :
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,0,1,0.1" AbsoluteLayout.LayoutFlags="All" Margin="0,20">
Solution:
Remove the margin and give a Y(here I use 0.05) to ViewControls like:
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,0.05,1,0.1" AbsoluteLayout.LayoutFlags="All" >
extra margin for absolute layout
There is a default space of stacklayout, the default value is 6.0.
Solution: you can add a spacing = -6 to remove it:
<StackLayout Orientation="Horizontal" BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" Spacing="-6">
Here is the full code:
<AbsoluteLayout>
<Image Source="Flower.jfif" Aspect="AspectFill" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" />
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,0.05,1,0.1" AbsoluteLayout.LayoutFlags="All" >
<StackLayout BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<Label Text="Relax" TextColor="White" FontSize="30" HorizontalOptions="Center" />
</StackLayout>
</AbsoluteLayout>
<AbsoluteLayout x:Name="ViewControlss" AbsoluteLayout.LayoutBounds="1,1,1,0.1" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#66000000">
<StackLayout Orientation="Horizontal" BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" Spacing="-6">
<Button Text="Profile" BackgroundColor="Yellow" TextColor="White" HorizontalOptions="FillAndExpand"/>
<Button Text="Meditate" BackgroundColor="Green" TextColor="White" HorizontalOptions="FillAndExpand"/>
<Button Text="Theme" BackgroundColor="Red" TextColor="White" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</AbsoluteLayout>
</AbsoluteLayout>
I have a xamarin forms app with a login screen.The problem I am facing is keyboard overlap when user enter details.The Username and password entering field is inside frame.
What I am getting
What I want
My Xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
BackgroundColor="#173F5F"
x:Class="app.Login">
<ScrollView>
<RelativeLayout>
<Image Source="backgrnd.png" Aspect="Fill"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Height}"/>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height}">
<StackLayout Orientation="Vertical" VerticalOptions="StartAndExpand" Margin="15,30,15,0">
<Image Source="logo.png" HorizontalOptions="Center" VerticalOptions="Center" HeightRequest="150" WidthRequest="150"></Image>
<Image Source="backlogo.png" HorizontalOptions="Center" VerticalOptions="Center" ></Image>
</StackLayout>
<StackLayout VerticalOptions="End" Margin="15,0,15,50" >
<Frame BackgroundColor="Snow" OutlineColor="Snow" HasShadow="True" HorizontalOptions="FillAndExpand" Padding="10,10,10,10"
CornerRadius="5"
Margin="15,10,15,0">
<StackLayout VerticalOptions="End" >
<StackLayout Orientation="Horizontal">
<Image Source="userlogo.png" HorizontalOptions="Start" HeightRequest="30" WidthRequest="30"></Image>
<Entry TextColor="Black"
x:Name="userName"
PlaceholderColor="Gray"
ReturnType="Next"
BackgroundColor="Snow"
Placeholder="User ID"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Image Source="locklogo.png" HorizontalOptions="Start" HeightRequest="30" WidthRequest="30"></Image>
<Entry TextColor="Black"
PlaceholderColor="Gray"
x:Name="password"
BackgroundColor="Snow"
VerticalOptions="Center"
Placeholder="Password"
IsPassword="true"
HorizontalOptions="FillAndExpand"/>
</StackLayout>
<Grid>
<Button x:Name="LoginButton" BackgroundColor="#4080a6" TextColor="White" Text="Sign In" Clicked="Login_Clicked" BorderRadius="7" BorderColor="#4080a6" BorderWidth = "2" HorizontalOptions="FillAndExpand" />
</Grid>
</StackLayout>
</Frame>
</StackLayout>
</StackLayout>
</RelativeLayout>
</ScrollView>
</ContentPage>
I tried Xam.Plugins.Forms.KeyboardOverlap but it doesnt solved my problem.Any help is appreciated.
Take a look at the answer here
I tried option 2 on Android and it works fine.
For your case,
try to add this Code to your page class
protected override void OnAppearing()
{
base.OnAppearing();
userName.Focused += InputFocused;
password.Focused += InputFocused;
userName.Unfocused += InputUnfocused;
password.Unfocused += InputUnfocused;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
userName.Focused -= InputFocused;
password.Focused -= InputFocused;
userName.Unfocused -= InputUnfocused;
password.Unfocused -= InputUnfocused;
}
void InputFocused(object sender, EventArgs args)
{
Content.LayoutTo(new Rectangle(0, -270, Content.Bounds.Width, Content.Bounds.Height));
}
void InputUnfocused(object sender, EventArgs args)
{
Content.LayoutTo(new Rectangle(0, 0, Content.Bounds.Width, Content.Bounds.Height));
}
Update
this code should be working on both Android and IOS
These are my image:
the green one is over the yellow, I used a grid for it...But it makes that when I tap the green one the tap doesn't work...when they were not in the same position, the green image worked.
this problem happens only in iphone devices
my grid:
<Grid>
<Image BackgroundColor="Yellow" Margin="10,10,0,0" Source="cadastrarCliqueFoto" Grid.Row="0" Grid.Column="0"/>
<Image BackgroundColor="Green" Source="cadastrarVoltar" Margin="10,10,0,0" VerticalOptions="Start" Grid.Row="0" Grid.Column="0" HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnClose"/>
</Image.GestureRecognizers>
</Image>
</Grid>
I've already tried 'InputTranparent = true' and it didn't work.
The complete code:
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-
namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
xmlns:controls="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin.Abstractions"
x:Class="neoFly_Montana.PopUp.CadastrarPopup"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
CloseWhenBackgroundIsClicked="False">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="1" Spacing="0">
<RelativeLayout>
<StackLayout x:Name="stack_cadast" VerticalOptions="Center"
HorizontalOptions="FillAndExpand" BackgroundColor="White"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=1,
Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Height,
Factor=1,
Constant=0}">
<StackLayout.Spacing>
<OnPlatform x:TypeArguments="x:Double"
iOS="10"/>
</StackLayout.Spacing>
<Grid>
<Image BackgroundColor="Yellow" InputTransparent="true" Margin="10,10,0,0" Source="cadastrarCliqueFoto" Grid.Row="0" Grid.Column="0"/>
<ContentView Grid.Row="0" Grid.Column="0" Margin="10,10,0,0" InputTransparent="true" VerticalOptions="Start" HorizontalOptions="Start">
<Image BackgroundColor="Green" Source="cadastrarVoltar">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnClose"/>
</Image.GestureRecognizers>
</Image>
</ContentView>
<Button Grid.Row="0" BackgroundColor="Blue" Opacity="0.3" Grid.Column="0" Clicked="OnClose"/>
</Grid>
<Entry x:Name="cadastrar_entry_nome" PlaceholderColor="Black" Margin="20, 10, 10, 0" Placeholder="Seu nome completo" HorizontalOptions="Fill"/>
<Entry x:Name="cadastrar_entry_email" PlaceholderColor="Black" Margin="20, 10, 10, 0" Placeholder="E-mail" HorizontalOptions="Fill"/>
<StackLayout Orientation="Horizontal" Margin="20, 10, 10, 0">
<StackLayout Spacing="0">
<Label Text="Data de nascimento" HorizontalOptions="Center" FontSize="Micro"/>
<DatePicker x:Name="cadastrar_date_datanasc"/>
</StackLayout>
<StackLayout Orientation="Horizontal" Padding="0,0,20,0" VerticalOptions="Fill" HorizontalOptions="EndAndExpand" Spacing ="20">
<Image x:Name="cadastrar_img_fem" Scale="1" Source="femDisable">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="FemClique"/>
</Image.GestureRecognizers>
</Image>
<Image x:Name="cadastrar_img_masc" Scale="1" Source="mascDisable">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="MascClique"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
</StackLayout>
<StackLayout Orientation="Horizontal" Margin="20, 10, 10, 0">
<Picker x:Name="cadastrar_picker_estado" SelectedIndexChanged="PickerEstado_SelectedindexChanged" Title="UF"/>
<ActivityIndicator x:Name="cadastro_cidade_ind" IsVisible="False" IsRunning="True"/>
<Picker x:Name="cadastrar_picker_cidade" IsVisible="False" Title="Cidade"/>
</StackLayout>
<Entry x:Name="cadastrar_entry_senha" PlaceholderColor="Black" IsPassword="true" Margin="20, 10, 10, 10" VerticalOptions="End" Placeholder="Senha" HorizontalOptions="Fill"/>
<Label x:Name="cadastrar_lbl_feedback" FontSize="Micro" HorizontalOptions="Center" Margin="0,0,10,10" TextColor="Red" IsVisible="False"/>
<!--Botão Cadastrar-->
<ContentView Margin="0,20,0,0" Padding="20,20,20,20" BackgroundColor="#700B0F">
<ContentView.GestureRecognizers>
<TapGestureRecognizer Tapped="CadastrarClique"/>
</ContentView.GestureRecognizers>
<Label Text="Cadastrar" VerticalOptions="Center" FontSize="Large" HorizontalOptions="Center" TextColor="White" Style="{StaticResource labelsfont}"/>
</ContentView>
</StackLayout>
<Grid HorizontalOptions="FillAndExpand"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
Property=Y,
ElementName=stack_cadast,
Factor=1,
Constant=-42.5}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=1,
Constant=0}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" WidthRequest="75" HeightRequest="75" Grid.Row="0" Grid.Column="1">
<ffimageloading:CachedImage BackgroundColor="Pink" VerticalOptions="End" HorizontalOptions="End" Source="cadastrarPhoto.png" x:Name="cadastrar_foto_perfil">
<ffimageloading:CachedImage.Transformations>
<fftransformations:CircleTransformation />
</ffimageloading:CachedImage.Transformations>
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer Tapped="ChamaPickerImage"/>
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
</StackLayout>
</Grid>
</RelativeLayout>
</StackLayout>
Try Absolute layout instead of grid.
<AbsoluteLayout>
<Image BackgroundColor="Yellow" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" Margin="10,10,0,0" Source="cadastrarCliqueFoto" />
<Image AbsoluteLayout.LayoutBounds="0,0,30,30" AbsoluteLayout.LayoutFlags="XProportional, YProportional" BackgroundColor="Green" Source="cadastrarVoltar" Margin="10,10,0,0" VerticalOptions="Start" HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnClose"/>
</Image.GestureRecognizers>
</Image>
</AbsoluteLayout>
I was facing the same issue. I have put the second Image in ContentView like below and it's working for me.
<Grid>
<Image BackgroundColor="Yellow" Margin="10,10,0,0" Source="cadastrarCliqueFoto" Grid.Row="0" Grid.Column="0"/>
<ContentView Grid.Row="0" Grid.Column="0" Margin="10,10,0,0">
<Image BackgroundColor="Green" Source="cadastrarVoltar" VerticalOptions="Start" HorizontalOptions="Start">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnClose"/>
</Image.GestureRecognizers>
</Image>
</ContentView>
</Grid>
-------- UPDATED -------
XAML code
<Grid>
<Image BackgroundColor="Yellow" Margin="10,10,0,0" Source="cadastrarCliqueFoto" Grid.Row="0" Grid.Column="0"/>
<ContentView Grid.Row="0" Grid.Column="0" Margin="10,10,0,0">
<Image BackgroundColor="Green" Source="cadastrarVoltar" VerticalOptions="Start" HorizontalOptions="Start"/>
</ContentView>
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="Close_Tapped"/>
</Grid.GestureRecognizers>
</Grid>
Code behind
void Close_Tapped(object sender, System.EventArgs e)
{
throw new NotImplementedException();
}
I am new to Xamarin.Forms in which I need loading message. How can I display the loading message?
Code:
<AbsoluteLayout>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All" Padding="30" >
<Grid>
//something
</Grid>
</StackLayout>
<ContentView x:Name="overlay" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" IsVisible="False" BackgroundColor="#C0808080" Padding="10, 0">
<ActivityIndicator WidthRequest="110" HeightRequest="70" IsRunning="True" IsVisible="True" Color="Black" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</ContentView>
</AbsoluteLayout>
Set IsVisible="True" for ContentView will show you the ActivityIndicator.
<ContentView x:Name="overlay" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" IsVisible="True" BackgroundColor="#C0808080" Padding="10, 0">
<ActivityIndicator WidthRequest="110" HeightRequest="70" IsRunning="True" IsVisible="True" Color="Black" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"/>
</ContentView>
If you are using MVVM and want full modal Loading Messages look at ACR User Dialogs for Xamarin and Windows. You can install it via nuget. You can find the sample application here.