How do I reference a static resource inside a resource dictionary? [duplicate] - xaml

My main resources look like this:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:converters="clr-namespace:Japanese"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary Source="/Resources/DetailRes.xaml" />
I have this resource file:
<?xml version="1.0" encoding="UTF-8" ?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Japanese.DetailRes">
<Style x:Key="DetailLabel" TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnPlatform x:TypeArguments="x:Double">
<On Platform="iOS" Value="35" />
<On Platform="Android" Value="35" />
</OnPlatform>
</Setter.Value>
</Setter>
<Setter Property="VerticalOptions" Value="Center" />
<Setter Property="LineBreakMode" Value="WordWrap" />
<Setter Property="HorizontalTextAlignment" Value="Center" />
</Style>
</ResourceDictionary>
In XAML I access it like this:
<t:BaseFrameButtonTemplate xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:t="clr-namespace:Japanese.Templates"
xmlns:local="clr-namespace:Japanese;assembly=Japanese"
x:Class="Japanese.Templates.RoundButtonText" x:Name="this" >
<Label Text="{Binding Text, Source={x:Reference this}}"
Style="{StaticResource DetailRes}"
x:Name="Label" />
</t:BaseFrameButtonTemplate>
I would like to access this in C# but do not know how to do it. I tried this but it does not find the resource:
Label.Style = (Style)Application.Current.Resources["DetailRes"];

You can use the TryGetValue to obtain a single from your ResourceDictionary:
if (Application.Current.Resources.TryGetValue("DetailLabel", out object style))
{
someLabel.Style = (Style)style;
}

Related

Xamarin Forms Tabbed Page Trigger properties not working

I'm trying to follow this sample
by using font awesome as icon for the tabbed page and use the triggers to change font color
but when I want to apply the style using font awesome I got an error that Property="IsChecked" does not exist for the target.
I noticed in the sample they are using shells how could I replicate that example using regular tabbed pages?
on the app.XAML I have the following
<OnPlatform x:TypeArguments="x:String"
x:Key="FontAwesomeSolid">
<On Platform="Android"
Value="Font5Solid.otf#Regular" />
<On Platform="iOS"
Value="FontAwesome5Free-Solid" />
</OnPlatform>
<OnPlatform x:TypeArguments="x:String"
x:Key="FontAwesomeRegular">
<On Platform="Android"
Value="Font5Regular.otf#Regular" />
<On Platform="iOS"
Value="FontAwesome5Free-Regular" />
</OnPlatform>
For the tabbed page I have the following
<?xml version="1.0" encoding="utf-8"?>
<TabbedPage x:Name="Tab" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="pages.Views.HomeTabbedPage">
<!--Pages can be added as references or inline-->
<TabbedPage.Resources>
<ResourceDictionary>
<Style TargetType="Tab" x:Key="FollowTab">
<Style.Triggers>
<Trigger TargetType="TabbedPage"
Property="IsChecked" Value="False">
<Setter Property="Icon" >
<Setter.Value>
<FontImageSource FontFamily="{StaticResource FontAwesomeRegular}" Glyph=""/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger TargetType="Tab"
Property="IsChecked" Value="True">
<Setter Property="Icon" >
<Setter.Value>
<FontImageSource FontFamily="{StaticResource FontAwesomeSolid}" Glyph=""/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</TabbedPage.Resources>
<ContentPage Title="sample page" />
</TabbedPage>
To replicate that in a normal TabbedPage you can try these steps:
1 - Create a converter to check TabbedPage.CurrentPage type:
public class SelectedTabTypeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
if (!(value is Page))
throw new ArgumentException("Expected value to be of type " + nameof(Page), nameof(value));
// if value is a NavigationPage check against its RootPage
if (value is NavigationPage navPage)
return navPage.RootPage?.GetType();
return value.GetType();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
2 - Add the x:Name attribute to the TabbedPage so we can reference it latter:
<TabbedPage x:Name="MyTabbedPage" ...
3 - Add the converter resource to TabbedPage.Resources:
<TabbedPage.Resources>
<ResourceDictionary>
<converters:SelectedTabTypeConverter x:Key="SelectedTabTypeConverter" />
</ResourceDictionary>
</TabbedPage.Resources>
4 - Add the pages and the DataTriggers:
<TabbedPage.Children>
<!-- Normal page tab default values -->
<views:OnePage Title="Page1">
<views:OnePage.Triggers>
<DataTrigger
TargetType="views:OnePage"
Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}"
Value="{x:Type views:OnePage}">
<Setter Property="Title" Value="Page1 Selected" />
</DataTrigger>
</views:OnePage.Triggers>
</views:OnePage>
<!-- NavigationPage tab -->
<NavigationPage Title="Page2">
<x:Arguments>
<views:TwoPage />
</x:Arguments>
<NavigationPage.Triggers>
<DataTrigger
TargetType="NavigationPage"
Binding="{Binding Source={x:Reference MyTabbedPage}, Path=CurrentPage, Converter={StaticResource SelectedTabTypeConverter}}"
Value="{x:Type views:TwoPage}">
<Setter Property="Title" Value="Page2 Selected" />
</DataTrigger>
</NavigationPage.Triggers>
</NavigationPage>
</TabbedPage.Children>

ResourceDictionary: System.InvalidCastException

I get an Exception throw and I cant figure out why. My guess is that Im overlooking something simple. The Exception gets thrown in ResourceSharingPage.xaml.g.cs
this is 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" x:Class="BookCodedotNet2.ResourceSharingPage">
<ContentPage.Resources>
<ResourceDictionary>
<x:String x:Key="fontSize">Large</x:String>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem ">
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
</Button>
</StackLayout>
</ContentPage>
If I remove
<Button.FontSize>
<StaticResourceExtension Key="fontSize"/>
</Button.FontSize>
I can build the app.
In the resources, try something like below. Use double value instead of string as FontSize is a double.
<ResourceDictionary>
<x:Double x:Key="fontSize">35</x:Double>
</ResourceDictionary>
You've defined the resource of type x:String. FontSize doesn't accept values of type String. It only accepts values of type Double or NamedSize. As you mentioned in the comment to Abdul Gani's answer, you should be defining NamedSize.
You are better off using the Style tag and setting the style of your Label that way. Follow SushiHangover's answer over here if you want to use Style instead.
You can use NamedSize in resource dictionary in this way:
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="fontSize" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
</Style>
<Color x:Key="NormalTextColor">Blue</Color>
<Style x:Key="MediumBoldText" TargetType="Button">
<Setter Property="FontSize" Value="Large" />
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<Button Text=" Carpe diem " Style="{StaticResource fontSize}"> </Button>
<Button Text="Test"
TextColor="{StaticResource NormalTextColor}"
Style="{StaticResource MediumBoldText}" />
</StackLayout>

Can't get FontSize for labels to work in ResourceDictionary when using OnPlatform

When using <Style TargetType="Label"> I cant get FontSize to work with NamedSize.
Using Xamarin.Forms version : 3.4.0.1008975
Working :
<Style TargetType="Label">
<Setter Property="FontSize" Value="Small" />
</Style>
NOT working :
<Style TargetType="Label">
<Setter Property="FontSize">
<Setter.Value>
<OnPlatform x:TypeArguments="x:String"
Android="Small"
iOS="Medium"/>
</Setter.Value>
</Setter>
</Style>
I have tried to change the TypeArguments to <OnPlatform x:TypeArguments="NamedSize" .../> with no success.
I am using other propertysetters with <OnPlatform .../> and they work as they should. Its just FontSize.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:App67"
x:Class="App67.MainPage">
<ContentPage.Resources>
<OnPlatform x:Key="textColor"
x:TypeArguments="Color">
<On Platform="WinPhone" Value="Red" />
<On Platform="Android" Value="Aqua" />
<On Platform="iOS" Value="#80FF80" />
</OnPlatform>
<OnPlatform x:Key="fontSize"
x:TypeArguments="Font">
<On Platform="WinPhone" Value="Bold,Large" />
<On Platform="Android" Value="Bold,Large" />
<On Platform="iOS" Value="Bold,Large" />
</OnPlatform>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout>
<Label Text="Check out my style." TextColor="{StaticResource textColor}" Font="{StaticResource fontSize}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>

Property Resources is null or is not IEnumerable

I got this error in break mode in visual studio 2015 when I was learning to make a Xamarin.Forms page.
Unhandled Exception:
Xamarin.Forms.Xaml.XamlParseException: Position 12:10. Property Resources is null or is not IEnumerable
My App.xaml code is below
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bisells.App">
<Application.Resources>
<!-- Application resource dictionary -->
<!-- colors -->
<!--<Color x:Key="HeaderTextColor">#585858</Color>
<Color x:Key="BodyTextColor">#C3C3C3</Color>-->
<Color x:Key="TimelineColor">#E4B6C3</Color>
<Color x:Key="HeaderTextColor">#3C3C3C</Color>
<Color x:Key="BodyTextColor">#869EAC</Color>
<Color x:Key="TimeColor">#A64C79</Color>
<!-- font families -->
<OnPlatform
x:Key="RegularFontFamily"
x:TypeArguments="x:String"
Android="sans-serif"
iOS="HelveticaNeue" />
<OnPlatform
x:Key="LightFontFamily"
x:TypeArguments="x:String"
Android="sans-serif-light"
iOS="HelveticaNeue-Light" />
<OnPlatform
x:Key="MediumFontFamily"
x:TypeArguments="x:String"
Android="sans-serif-medium"
iOS="HelveticaNeue-Medium" />
<!-- fonts -->
<Font
x:Key="HeaderFont"
FontFamily="{StaticResource MediumFontFamily}"
FontSize="30" />
<Font
x:Key="SubHeaderFont"
FontFamily="{StaticResource MediumFontFamily}"
FontSize="18" />
<Font
x:Key="TitleFont"
FontFamily="{StaticResource MediumFontFamily}"
FontSize="20" />
<Font
x:Key="BodyFont"
FontFamily="{StaticResource RegularFontFamily}"
FontSize="18" />
<!-- styles -->
<Style x:Key="PageHeaderLabel" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource HeaderTextColor}" />
<Setter Property="Font" Value="{StaticResource HeaderFont}" />
</Style>
<Style x:Key="SubHeaderLabel" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource BodyTextColor}" />
<Setter Property="Font" Value="{StaticResource SubHeaderFont}" />
</Style>
<Style x:Key="ClassTimeLabel" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource TimeColor}" />
<Setter Property="Font" Value="{StaticResource TitleFont}" />
</Style>
<Style x:Key="ClassNameLabel" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource HeaderTextColor}" />
<Setter Property="Font" Value="{StaticResource TitleFont}" />
</Style>
<Style x:Key="ClassInstructorLabel" TargetType="Label">
<Setter Property="TextColor" Value="{StaticResource BodyTextColor}" />
<Setter Property="Font" Value="{StaticResource BodyFont}" />
</Style>
</Application.Resources>
</Application>
Also xamarin not showing where exactly the exception occuring
You forgot the ResourceDictionary tag:
<Application.Resources>
<ResourceDictionary>
<!-- Application resource dictionary -->
<!-- colors -->
<!--<Color x:Key="HeaderTextColor">#585858</Color>
<Color x:Key="BodyTextColor">#C3C3C3</Color>-->
<Color x:Key="TimelineColor">#E4B6C3</Color>
<Color x:Key="HeaderTextColor">#3C3C3C</Color>
<Color x:Key="BodyTextColor">#869EAC</Color>
<Color x:Key="TimeColor">#A64C79</Color>
</ResourceDictionary>
</Application.Resources>
Define style in App.xaml like this:
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="PlatformFontSample.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="FontFamilyName" x:TypeArguments="x:String" iOS="MarkerFelt-Thin" Android="OpenSans" WinPhone="Segoe UI" />
<Style x:Key="FontLabel" TargetType="Label">
<Setter Property="FontFamily" Value="{DynamicResource FontFamilyName}" />
</Style>
</ResourceDictionary>
</Application.Resources>
and then Use in xaml:
<Label Text="{Binding Name}" Style="{DynamicResource FontLabel}" FontSize="Medium" FontAttributes="Bold" LineBreakMode="NoWrap"/>

In Xamarin XAML, how do I set a Constraint on a RelativeLayout using a Style?

I am struggling to work out the XAML syntax to apply constraints to a RelativeLayout using a Style.
The first piece of Xamarin XAML below shows a pair of nested RelativeLayout elements used to construct a simple layout (the inner element simply puts a margin around an area to which I can add other content). This version of the code builds and runs fine on iOS and Android.
<?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="App2.Page1">
<RelativeLayout BackgroundColor="Gray">
<RelativeLayout BackgroundColor="Maroon"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.9,Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.9,Constant=0}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.05,Constant=0}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.05,Constant=0}">
<BoxView Color="Yellow"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.25,Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.25,Constant=0}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.25,Constant=0}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.25,Constant=0}"/>
</RelativeLayout>
</RelativeLayout>
</ContentPage>
What I would like to do it use the same layout on multiple pages, so I want to put the RelativeLayout constraints into a Style. This second piece of code does not parse or run, but I hope it shows what I am trying to achieve. If I can get the right syntax for this, the idea is that the Style can then be moved out into a shared file, so I can easily re-use it across multiple instances of ContentPage.
<?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="App2.Page2">
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="LayoutStyle" TargetType="RelativeLayout">
<Setter Property="BackgroundColor" Value="Maroon"/>
<Setter Property="HeightConstraint">
<Setter.Value>"Type=RelativeToParent,Property=Height,Factor=0.9,Constant=0"</Setter.Value>
</Setter>
<Setter Property="WidthConstraint">
<Setter.Value>"Type=RelativeToParent,Property=Width,Factor=0.9,Constant=0"</Setter.Value>
</Setter>
<Setter Property="YConstraint">
<Setter.Value>"Type=RelativeToParent,Property=Height,Factor=0.05,Constant=0</Setter.Value>
</Setter>
<Setter Property="XConstraint">
<Setter.Value>"Type=RelativeToParent,Property=Width,Factor=0.05,Constant=0</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<RelativeLayout BackgroundColor="Gray">
<RelativeLayout Style="LayoutStyle">
<BoxView Color="Yellow"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.25,Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.25,Constant=0}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=0.25,Constant=0}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=0.25,Constant=0}"/>
</RelativeLayout>
</RelativeLayout>
</ContentPage>
Please can anyone help me out with the syntax for doing this?
This is a link to a complete example (which obviously requires Xamarin to be installed and needs the nuget packages to be restored): XAML Layout Example
Try this:
<ResourceDictionary>
<Style x:Key="LayoutStyle" TargetType="RelativeLayout">
<Setter Property="BackgroundColor" Value="Maroon"/>
<Setter Property="RelativeLayout.HeightConstraint" Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.9,Constant=0}"/>
<Setter Property="RelativeLayout.WidthConstraint" Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.9,Constant=0}"/>
<Setter Property="RelativeLayout.YConstraint" Value="{ConstraintExpression RelativeToParent,Property=Height,Factor=0.05,Constant=0}"/>
<Setter Property="RelativeLayout.XConstraint" Value="{ConstraintExpression RelativeToParent,Property=Width,Factor=0.05,Constant=0}"/>
</Style>
</ResourceDictionary>