Xamarin Forms NavigationPage.TitleView RTL, the content disappered - xamarin

I have a xamarin.forms app that supports RTL, but when i convert a Page to RTL the NavigationPage.TitleView text disapears.
The NavigationPage.TitleView Code:
<NavigationPage.TitleView>
<Label Text="{Binding Title}" Style="{StaticResource TittleLabel}" HorizontalTextAlignment="Start" HorizontalOptions="Start" VerticalOptions="CenterAndExpand"></Label>
</NavigationPage.TitleView>
This is the Result screen.
Thanks in Advance.

For RTL, the Label having RTL issues. Please find the issue link below.
https://github.com/xamarin/Xamarin.Forms/issues/3611
When setting RTL to Page, the title view is disappeared. you can report to the Xamarin team. For instead of setting a title through Label, directly setting title property of ContentPage like below,
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="RTL"
FlowDirection="RightToLeft">
It's working but RTL is not applying. But the title is displayed. You can report this issue also.

I guess maybe the binding do not work. I make a sample for your reference.
MainPage.xaml
<StackLayout>
<Button Clicked="Button_Clicked" Text="Title View Page" />
</StackLayout>
MainPage.xaml.cs
private void Button_Clicked(object sender, EventArgs e)
{
Navigation.PushAsync(new TitleViewPage());
}
TitleViewPage.xaml
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="TittleLabel" TargetType="Label">
<Setter Property="TextColor" Value="Green" />
<Setter Property="FontSize" Value="Large" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<NavigationPage.TitleView>
<StackLayout>
<Label
HorizontalOptions="Start"
HorizontalTextAlignment="Start"
Style="{StaticResource TittleLabel}"
Text="{Binding Title}"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</NavigationPage.TitleView>
<ContentPage.Content>
<StackLayout>
<Label
HorizontalOptions="CenterAndExpand"
Text="Welcome to TitleView Page!"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
TitleViewPage.xaml.cs
public string Title { get; set; }
public TitleViewPage()
{
InitializeComponent();
Title = "My TitleView";
this.BindingContext = this;
}
App.xaml.cs
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
Updated:
When you set the FlowDirection to RightToLeft, the titleview could be seen on horizontal screen.
On the Right-to-left localization document, it lists the limitations.
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/localization/right-to-left
NavigationPage button location, toolbar item location, and transition animation is controlled by the device locale, rather than the FlowDirection property.
This question has also be reported. You could follow the update . https://github.com/xamarin/Xamarin.Forms/issues/9083

this aproach worked for me:
-set RTL-FlowDirection for main-layout (wrapper) of ContentPage's content (instead of ContentPage)
App.xaml
<Application.Resources>
<ResourceDictionary>
<Style x:Key="PageTitleStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="EndAndExpand"/>
<Setter Property="Padding" Value="0,0,5,0"/>
</Style>
</ResourceDictionary>
</Application.Resources>
MainPage.xaml
<ContentPage ....>
<NavigationPage.TitleView >
<Label Text="{Binding Title}" Style="{StaticResource PageTitleStyle}" />
</NavigationPage.TitleView>
<StackLayout FlowDirection="RightToLeft">
....
</StackLayout>
</ContentPage>

Related

Control template Binding Not working in MVVM Cross Xamarin Forms

I am currently working on a Xamarin Forms project which is using MVVMCross. In App.xaml i created a control template as follows
<ControlTemplate x:Key="ContentPageTemplate">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowSpacing="0" RowDefinitions="Auto,Auto,*">
<!--StackLayout as Header-->
<StackLayout Grid.Row="0" HeightRequest="6" BackgroundColor="{StaticResource SecondaryBrandColor}"></StackLayout>
<Frame Padding="0" Grid.Row="1" >
<Label Grid.Row="1" Text="Server Not Available" BindingContext="{TemplateBinding BindingContext}"
Style="{StaticResource ServerAvailableLabel}"
IsVisible="{TemplateBinding Parent.BindingContext.IsServerAvailableLabelVisible}"/>
</Frame>
<!--Content Page Body-->
<ContentPresenter Grid.Row="2" BackgroundColor="{StaticResource PrimaryBodyColor}">
</ContentPresenter>
</Grid>
</ControlTemplate>
Now i am using this control template in contentPage as follows
<views:MvxContentPage xmlns:views="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Project.UI.Views.ReqView"
ControlTemplate="{StaticResource ContentPageTemplate}"
Title="Reqs">
</views:MvxContentPage>
In the view model i am trying to make the label visible and invisible as follows
public bool _isServerAvailableLabelVisible = false;
public bool IsServerAvailableLabelVisible
{
get
{
return _isServerAvailableLabelVisible;
}
set
{
SetProperty(ref _isServerAvailableLabelVisible, value);
}
}
The problem i am facing now is, by default the label is being visible and also it is not updating even when i am setting the value as false.
What am i missing ?
I had exactly the same issue !
After one day I found the following solution which works for me.
I added BindingContext="{TemplateBinding BindingContext.DataContext}"into the Grid and change the IsVisible property by IsVisible="{Binding IsServerAvailableLabelVisible}"
Here the recap that you can try, hope it will work for you too !
For information I use Xamarin.Forms 4.8.0 & MvvmCross 6.3.1
<ControlTemplate x:Key="ContentPageTemplate">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowSpacing="0" RowDefinitions="Auto,Auto,*"
BindingContext="{TemplateBinding BindingContext.DataContext}">
<!--StackLayout as Header-->
<StackLayout Grid.Row="0" HeightRequest="6" BackgroundColor="{StaticResource SecondaryBrandColor}"></StackLayout>
<Frame Padding="0" Grid.Row="1" >
<Label Grid.Row="1" Text="Server Not Available"
Style="{StaticResource ServerAvailableLabel}"
IsVisible="{Binding IsServerAvailableLabelVisible}"/>
</Frame>
<!--Content Page Body-->
<ContentPresenter Grid.Row="2" BackgroundColor="{StaticResource PrimaryBodyColor}">
</ContentPresenter>
</Grid>
</ControlTemplate>
Are you sure that the OnPropertyChanged Event gets fired when you chcange the value?
If yes then you need to check the binding context of the view
If no you need to fire it manually (as mentioned in the MVVMCross documentation)
private string _myProperty;
public string MyProperty
{
get => _myProperty;
set
{
_myProperty = value;
RaisePropertyChanged(() => MyProperty);
// take any additional actions here which are required when MyProperty is updated
}
}

Can I use something like a control template in Xamarin to surround a new object?

My application has objects that are surrounded by this:
<StackLayout HeightRequest="49" BackgroundColor="Red" Orientation="Vertical" Margin="0" >
<Grid VerticalOptions="CenterAndExpand">
     <!-- XAML here -->
    </Grid>
</StackLayout>
I would like to make it so that I don't need to enter the XAML on the 1st, 2nd, last and next to last lines each time.
Can I use something like a control template to avoid doing this and if so how would I use it?
You will need to use a combination of ContentPresenter and ControlTemplate (as mentioned in the note on this page)
On a ContentPage (or ContentView), the Content property can be assigned and the ControlTemplate property can also be set. When this occurs, if the ControlTemplate contains a ContentPresenter instance, the content assigned to the Content property will be presented by the ContentPresenter within the ControlTemplate.
<ControlTemplate x:Key="DefaultTemplate">
<StackLayout HeightRequest="49" BackgroundColor="Red"
Orientation="Vertical" Margin="0">
<Grid VerticalOptions="CenterAndExpand">
<ContentPresenter /> <!-- This line is replaced by actual content -->
</Grid>
</StackLayout>
</ControlTemplate>
Usage:
<ContentView ControlTemplate="{StaticResource DefaultTemplate}">
<!-- XAML here (basically the view that is to be surrounded by above layout) -->
<Label TextColor="Yellow" Text="I represent the content" />
</ContentView>
Yes, Xamarin also provide the Control Template functionalities in XAML.
Write a below code in App.xaml
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="TealTemplate">
<Grid>
<Label Text="Control Template Demo App"
TextColor="White"
VerticalOptions="Center" />
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
Call the template in side ContentPage
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="SimpleTheme.HomePage">
<ContentView x:Name="contentView" Padding="0,20,0,0"
ControlTemplate="{StaticResource TealTemplate}">
<StackLayout VerticalOptions="CenterAndExpand">
<Label Text="Welcome to the app!" HorizontalOptions="Center" />
<Button Text="Change Theme" Clicked="OnButtonClicked" />
</StackLayout>
</ContentView>
</ContentPage>

Xamarin change font in XAML

How can I change the font of a label in Xamarin.Forms XAML?
Predictions are not available for font family attribute in XAML.
I tried 2 or 3 fonts like 'Arial' in font family, but it's not working.
Help me to resolve this.
<StackLayout Orientation="Vertical">
<Label Text="Welcome !"
VerticalOptions="Start"
HorizontalOptions="StartAndExpand"
FontFamily="Arial"
/>
</StackLayout>
store ttf file Location
Android: YouNameSpace.Droid/Assets/Poppins-Light.ttf
Ios: YouNameSpace.iOS/Resources/fonts/Poppins-Light.ttf
for iOS Need to put Below line in info.plist file
create static resource in App.xaml
<Application.Resources>
<ResourceDictionary>
<!-- FontFamily -->
<OnPlatform x:Key="PoppinsBold"
x:TypeArguments="x:String"
iOS="Poppins-Bold"
Android="Poppins-Bold.ttf#Poppins"/>
<OnPlatform x:Key="PoppinsLight"
x:TypeArguments="x:String"
iOS="Poppins-Light"
Android="Poppins-Light.ttf#Poppins" />
<!-- style for Lable -->
<Style x:Key="PoppinsBoldLabelStyle"
TargetType="{x:Type Label}">
<Setter Property="FontFamily"
Value="{StaticResource PoppinsBold}" />
</Style>
<Style x:Key="PoppinsLightLabelStyle"
TargetType="{x:Type Label}">
<Setter Property="FontFamily"
Value="{StaticResource PoppinsLight}" />
</Style>
</ResourceDictionary>
</Application.Resources>
use static resource in Lable
<Label Text="Hello" Style="{StaticResource PoppinsBoldLabelStyle}"/>
I resolved it by copying the font in 'Assets' folder for Android and changed the code as following:
<StackLayout Orientation="Vertical">
<Label Text="Hello Forms with XAML" FontFamily="ariblk.ttf#ariblk"/>
<Label Text="New Line following the first line " FontFamily="chiller.ttf#chiller" />
</StackLayout>
Please refer to this, and here is official demo.
Or you can use Custom renderers.
Here download the Arial, and put your Assets/Fonts folder.
MyLabel in your PCL:
namespace FontTes
{
public class MyLabel:Label
{
}
}
MyLabelRender in your Android platform:
using Android.Content;
using Android.Graphics;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(FontTes.MyLabel), typeof(FontTes.Droid.MyLabelRender))]
namespace FontTes.Droid
{
class MyLabelRender: LabelRenderer
{
public MyLabelRender(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
var label = (TextView)Control;
label.Typeface = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, "Fonts/arial.ttf");
}
}
}
PCL's MainPage.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FontTes;assembly=FontTes"
x:Class="FontTes.MainPage">
<StackLayout>
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="Center"
HorizontalOptions="Center"/>
<local:MyLabel
Text="Welcome to Xamarin.Forms!"
VerticalOptions="Center"
HorizontalOptions="Center"/>
</StackLayout>
</ContentPage>

Bind to ContentPage Title From ControlTemplate

I have a fairly simple Xamarin.Forms App, with a ContentPage and a ControlTemplate in an App.Xaml ResourceDictionary
I am trying to bind to the ContentPage.Title Property of the parent ContentPage. however the following doesn't seem to work..
ContentPage
<ContentPage
x:Class="Inhouse.Mobile.Pcl.Views.MoveLocationView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
ControlTemplate="{StaticResource MainPageTemplate}"
Title="Move Location"
...
ControlTemplate
<?xml version="1.0" encoding="utf-8" ?>
<Application
x:Class="Inhouse.Mobile.Pcl.App"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="MainPageTemplate">
<cut for Brevity ...>
<StackLayout BackgroundColor="#333333">
<Label Text="{TemplateBinding Page.Title}"></Label>
</StackLayout>
<ScrollView Grid.Row="2" >
<ContentPresenter VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" />
</ScrollView>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
I'm not sure what i should actually be binding too
i.e my attempt was
<Label Text="{TemplateBinding Page.Title}"></Label>
My problem was that i was in a StackLayout and needed to set
HorizontalOptions="StartAndExpand" so i could see it.
Additionally, Title was sufficient
{TemplateBinding Title}
I.e
<StackLayout Grid.Row="1" BackgroundColor="#333333">
<Label Text="{TemplateBinding Title}" TextColor="AliceBlue" HorizontalOptions="StartAndExpand"/>
</StackLayout>

how to define/override Style for ContentView when it is child of ContentPage

I have contentview as below
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:convertors="clr-namespace:myApp.Convertors;assembly=myApp"
x:Class="myApp.cwPart">
<ContentView.Content>
<StackLayout Orientation="Horizontal"
BackgroundColor="White">
<RelativeLayout Style="{StaticResource myStyle}"
HorizontalOptions="Start"
VerticalOptions="Center">
I am referencing this ContentView inside multiple ContentPages as example one below. Every ContentPage should set different BackgroundColor, Height and Width. That's why I thought that style should be defined in the ContentPage but it is throwing error that it is not recognized. How can I achieve this?
PS, interesting thing I am using Gorilla player to achieve such changes and Gorilla player doesn't return any error :)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:convertors="clr-namespace:myApp.Convertors;assembly=myApp"
xmlns:c="clr-namespace:myApp;assembly=myApp"
x:Class="myApp.AppLogsPage"
Title="{Binding AppName}"
x:Name="AppLogsPage">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="myStyle" TargetType="RelativeLayout">
<Setter Property="HeightRequest" Value="148"/>
<Setter Property="WidthRequest" Value="80"/>
<Setter Property="BackgroundColor" Value="White"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout x:Name="MainHolder">
<c:cwPart />
...
If I define ContentView Resources as below, it works fine but I am not able to override the Style defined inside ContentView
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:convertors="clr-namespace:myApp.Convertors;assembly=myApp"
x:Class="myApp.cwPart">
<ContentView.Resources>
<ResourceDictionary>
<Style x:Key="myStyle" TargetType="RelativeLayout">
<Setter Property="HeightRequest" Value="148"/>
<Setter Property="WidthRequest" Value="80"/>
<Setter Property="BackgroundColor" Value="White"/>
</Style>
</ResourceDictionary>
</ContentView.Resources>
<ContentView.Content>
<StackLayout Orientation="Horizontal" BackgroundColor="White">
<RelativeLayout Style="{StaticResource myStyle}"
HorizontalOptions="Start" VerticalOptions="Center" >
There are many issues i would change in your approach but let's keep it simple. First of all i would use contentview with control template as;
in App.xaml;
<ControlTemplate x:Key="MyControlTemplate">
<StackLayout Orientation="Horizontal" BackgroundColor="White">
<RelativeLayout HorizontalOptions="Start" VerticalOptions="Center" />
</StackLayout>
</ControlTemplate>
then in your page.xaml
<ContentView ControlTemplate={StaticResource MyControlTemplate}/>
if you want to set individual styles for every page then you can create a control template for each of them.
To create a WPF like user control;
in App.xaml;
<ControlTemplate x:Key="MyControlTemplate">
<StackLayout Orientation="Horizontal" BackgroundColor="White">
<RelativeLayout HorizontalOptions="Start" VerticalOptions="Center" />
</StackLayout>
</ControlTemplate>
in the same project
public class CustomView: ContentView
{
public CustomView()
{
ControlTemplate = (ControlTemplate)Application.Current.Resources.FirstOrDefault(x => x.Key == "MyControlTemplate").Value;
}
}
then you can use CustomView control/view in any xaml page. Don't forget to add xaml namespace of the CustomView in consuming xaml page.

Resources