All Entry inputs are red when selected - xamarin

Whenever I tap on a entry component while debugging the color when selected is red. I have not set this anywhere so I don't understand why this is happening.
My resource file has this for the color of "TextColor"
<Color x:Key="TextColor">#FFFFFF</Color>
My Xaml for page :
<?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="MyApp.Views.RegisterPage"
BackgroundColor="{StaticResource PrimaryColor}">
<ContentPage.Content>
<FlexLayout Direction="Column" Margin="30"
JustifyContent="Center" >
<StackLayout Margin ="0,0,0,15">
<Entry PlaceholderColor="{StaticResource TextColor}" TextColor="{StaticResource TextColor}" Placeholder="First Name"/>
<Entry PlaceholderColor="{StaticResource TextColor}" TextColor="{StaticResource TextColor}" Placeholder="Last Name " />
<Entry PlaceholderColor="{StaticResource TextColor}" TextColor="{StaticResource TextColor}" Placeholder="E-Mail " />
<Entry PlaceholderColor="{StaticResource TextColor}" TextColor="{StaticResource TextColor}" Placeholder="Password" />
<Entry PlaceholderColor="{StaticResource TextColor}" TextColor="{StaticResource TextColor}" Placeholder="Retype Password" />
</StackLayout>
<StackLayout Margin ="0,30,0,0">
<Button TextColor="{StaticResource TextColor}" BackgroundColor="{StaticResource AccentColor}" Padding="20" Text="Register"/>
</StackLayout>
</FlexLayout>
</ContentPage.Content>
How it looks

That particular color in android represents the Accent Color. You can override android styles for accent color to define that color.
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primaryDark</item>
<item name="colorAccent">#your-color-here </item>
</style>
</resources>
You should be able to find Styles.xml file in your Xamarin Android Specific project inside resources folder. Hope this helps.
Note : This will change the accent color of other controls as well. If you only want to change such color for Entry only. You have to write the Custom Renderer for that. Let me know If you want to go that way.

Related

Multi Data Trigger In Xamarin Forms

I am attempting to allow click on my button ONLY if the two text fields are not null. However, I am getting the compile error of
Type multi-data trigger not found
Below is my syntax, how should I change it so it executes as desired?
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" >
<ContentPage.Content>
<StackLayout Orientation="Vertical" Padding="30" Spacing="40">
<BoxView HeightRequest="10"/>
<Frame BackgroundColor="#BF043055" HasShadow="False">
<StackLayout Orientation="Vertical" Spacing="10">
<Entry x:Name="Email" Text="{Binding Email}" Placeholder="Email"
PlaceholderColor="Red" HeightRequest="50"
Keyboard="Email" TextColor="Black" />
<Entry x:Name="Password" Text="{Binding Password}" Placeholder="Password"
PlaceholderColor="Red" HeightRequest="50"
IsPassword="True" TextColor="Black" />
</StackLayout>
</Frame>
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
EDIT
I edited my syntax to the below but I am getting a compile error of:
No property, bindable property, or event found for 'ElementName', or mismatching type between value and property.
<Button x:Name="loginbutton" Command="{Binding SubmitCommand}" Text="Login" TextColor="White"
FontAttributes="Bold" FontSize="Large" HorizontalOptions="FillAndExpand"
BackgroundColor="#088da5" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<MultiTrigger TargetType="{x:Type Button}">
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Email, Path=Text.Length, Mode=OneWay}" Value="0"/>
<Condition Binding="{Binding ElementName=Password, Path=Text.Length, Mode=OneWay}" Value="0"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False"/>
</MultiTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
MultiDataTrigger is specific to WPF. Xamarin uses MultiTrigger, which essentially does the same thing. Have a look through this blog post to see how to implement Triggers in Xamarin Forms.

How can I create a XAML template that acts as a wrapper for elements?

I have this XAML code:
<Frame CornerRadius="1" HasShadow="false" Margin="10"
BackgroundColor="White" BorderColor="Silver" Padding="0" >
<StackLayout Orientation="Vertical" Spacing="0" Padding="0" >
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</StackLayout>
</Frame>
Does anyone have any ideas on how I could replace this with something like:
<template:NewFrame>
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</template:NewFrame>
As you can see I'm familiar with how to create and use templates that contain elements, but I don't know how to create a template that I can use as a wrapper for elements.
One way is the one that #Tom said and another one is using a Control template that is basically what you want I think.
Even tough the docs said that
Xamarin.Forms control templates provide the ability to easily theme and re-theme application pages at runtime. This article provides an introduction to control templates
you can use the control template as a wrapper using it in a ContentView (I've done it and it works perfectly).
In your case you'd have to do a ContentView and fill the ContentView.ControlTemplate with your layout of the wrapper:
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:... your namespaces
x:Class="YourNamespace.NewFrame">
<ContentView.ControlTemplate>
<ControlTemplate>
<Frame CornerRadius="1" HasShadow="false" Margin="10"
BackgroundColor="White" BorderColor="Silver" Padding="0" >
<ContentPresenter />
</Frame>
</ControlTemplate>
</ContentView.ControlTemplate>
</ContentView>
As you can see there is a ContentPresenter that is what is going to be replaced with your content (one thing to take into account is that the ContentPresenter allows only one child so you wil have to put your StackLayout inside)
<template:NewFrame>
<StackLayout Orientation="Vertical" Spacing="0" Padding="0" >
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</StackLayout>
</template:NewFrame>
Another way would be to do a custom layout but it's more complicated and I wouldn't go that way to do that layout wrapper.
C#:
public class CustomFrame : Frame
{
public CustomEditor()
{
CornerRadius = 1;
HasShadow = false;
Margin = 10;
BackgroundColor = Color.White;
BorderColor = Color.Silver;
Padding = 0;
}
}
Usage:
<template:CustomFrame>
<StackLayout
Orientation="Vertical"
Spacing="0"
Padding="0" >
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</StackLayout>
</template:CustomFrame>

How can I create a new Xamarin Element based on a Frame with a StackLayout inside of it?

I have a Frame with a StackLayout inside of it:
<Frame CornerRadius="1" HasShadow="false" Margin="10"
BackgroundColor="White" BorderColor="Silver" Padding="0" >
<StackLayout Orientation="Vertical" Spacing="0" Padding="0" >
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</StackLayout>
</Frame>
Can I create a new object called NewFrame that is the same as the Frame with the StackLayout inside?
<template:NewFrame>
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</template:NewFrame>
or
<template:NewFrame>
<xaml:ABCXaml />
</template:NewFrame>
or
<template:NewFrame>
<Label Text="X" />
</template:NewFrame>
It was suggested I use a Custom View but I have looked and can not find an example of this where it contains other elements inside.
Right-Click at the desired position in your Shared Project (or PCL) in your Solution Explorer (I would recommend adding a folder named "Views" or "CustomViews" and creating the item inside that folder), select "Add new item" and choose "Content View" (without (C#) behind it. The filename should be something like "View1.xaml", you can change that due to your liking, however the important thing is that the xaml extension is there.
This will create a new ContentView with a xaml and xaml.cs file.
Inside the xaml file you can declare your xaml code posted above and write any code necessary into the xaml.cs file.
Now you can add a namespace declaration to the page you want to put your view into:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
...
xmlns:customs="clr-namespace:YourNamespace.Views;assembly=YourNamespace"
and declare the element in that Page's or any layout's content:
<customs:CustomViewName ... />
If you want to be able to control the element's behaviour you can add BindableProperties in the codebehind.
For more in-depth information on that, you might want to take a look into this article: https://visualstudiomagazine.com/articles/2017/10/01/add-custom-controls.aspx
Use a ContentView along with a ControlTemplate to create a Custom Control. This way you can create a new control called NewFrame, write the XAML for your control and then use the <ContentPresenter> tag inside your <ControlTemplate> to assign where you'd like your content to be.
Like so:
.
└── NewFrame
├── NewFrame.cs
└── NewFrame.xaml -> Is a ResourceDictionary
NewFrame.cs:
namespace TestApp.Controls
{
public partial class NewFrame : ContentView
{
}
}
NewFrame.xaml:
<ResourceDictionary
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:newFrame="clr-namespace:TestApp.Controls"
x:Class="Namespace.For.A.ResourceDictionary">
<Style TargetType="newFrame:NewFrame">
<Setter Property="ControlTemplate">
<Setter.Value>
<ControlTemplate>
<ContentView BackgroundColor="Transparent">
<Frame CornerRadius="1" HasShadow="false" Margin="10" BackgroundColor="White" BorderColor="Silver" Padding="0" >
<StackLayout Orientation="Vertical" Spacing="0" Padding="0">
<ContentPresenter/>
</StackLayout>
</Frame>
</ContentView>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
ConsumingYourControl.xaml:
<template:NewFrame>
<template:NewFrame.Content>
<xaml:PtiXaml />
<template:LineTemplate />
<xaml:AtiXaml />
<template:LineTemplate />
<xaml:StiXaml />
</template:NewFrame.Content>
</template:NewFrame>
<template:NewFrame>
<template:NewFrame.Content>
<xaml:ABCXaml />
</template:NewFrame.Content>
</template:NewFrame>
<template:NewFrame>
<template:NewFrame.Content>
<Label Text=""/>
</template:NewFrame.Content>
</template:NewFrame>

How to set FlexLayout height automatically according to its children height

I'm trying to create a FlexLayout without specifying its height as I am supposing it will get it from its children height. When I'm doing so, the FlexLayout is not displayed at all. Here is a simple code:
<FlexLayout Direction="Column">
<Button Text="Test Button" />
<!-- Here I'm trying to create FlexLayout without specifying its height -->
<FlexLayout JustifyContent="Start" AlignItems="Start" AlignContent="Start" BackgroundColor="Blue" Direction="RowReverse" Wrap="Wrap">
<Label Text="Test Label" HeightRequest="50" WidthRequest="50" BackgroundColor="Yellow" />
</FlexLayout>
</FlexLayout>
I tried everything but nothing works unless I specify HeightRequest or FlexLayout.Basis for the (inner) FlexLayout.
Any Suggestions will be appreciated.
If I changed the first FlexLayout to StackLayout as follows, it will work. This is so weird as I assume it should work without changing it to StackLayout :
<StackLayout Orientation="Vertical" Spacing="0">
<Button Text="Test Button" />
<FlexLayout JustifyContent="Start" AlignItems="Start" AlignContent="Start" BackgroundColor="Blue" Direction="RowReverse" Wrap="Wrap">
<Label Text="Test Label" HeightRequest="50" WidthRequest="50" BackgroundColor="Yellow" />
</FlexLayout>
</StackLayout>

Xamarin.Forms - Label not centered

I've got a StackView which contains 2 Labels. One is normal text, and the other one is a FontAwesome Icon.
Anyhow both Labels are not centered vertically inside the StackView. Here is the Code for them:
The Styles:
<Style x:Key="FAIconedLabel" TargetType="Label">
<Setter Property="TextColor" Value="White"/>
<Setter Property="FontSize" Value="40" />
<Setter Property="Margin" Value="0" />
</Style>
<Style x:Key="EmailLabel" TargetType="Label">
<Setter Property="TextColor" Value="White"/>
<Setter Property="FontSize" Value="20" />
</Style>
And the Views itself
<!-- Top Right -->
<Grid BackgroundColor="{StaticResource LamaControlGray}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Width,Factor=1,Constant=-400}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Width,Factor=0,Constant=400}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Height,Factor=0,Constant=40}" >
<StackLayout Orientation="Horizontal" HorizontalOptions="End" VerticalOptions="FillAndExpand" BackgroundColor="Red">
<Label x:Name="LblUserEmail" Margin="0,0,10,0" Text="{Binding UserEmail}" VerticalOptions="FillAndExpand" Style="{StaticResource EmailLabel}"/>
<fal:FontAwesomeLabel Text="{Binding SettingsIcon}" BackgroundColor="Green" VerticalOptions="CenterAndExpand" Style="{StaticResource FAIconedLabel}" />
</StackLayout>
</Grid>
Do I miss something here?
Edit 1
I added a BackgroundColor to see, if the Label actually fills the StackView
Edit 2
After cleaning and rebuilding the solution, the email Label is centered now. But the Iconed one still remains at the bottom
Yes you are missing something.
You're not setting it to be centered vertically.
Either
<Label x:Name="LblUserEmail" Margin="0,0,10,0" Text="{Binding UserEmail}" VerticalOptions="FillAndExpand" VerticalTextAlignment="Center" Style="{StaticResource EmailLabel}"/>
or
<Label x:Name="LblUserEmail" Margin="0,0,10,0" Text="{Binding UserEmail}" VerticalOptions="CenterAndExpand" Style="{StaticResource EmailLabel}"/>

Resources