Accessing global resources in App.xaml from ContentView - xamarin

I have a color defined in my App.xaml resource dictionary. When I try to reference it in a ContentView I get a run time exception:
StaticResource not found for key NavbarBackground
Do I need to merge the resource dictionary in App.xaml?
App.xaml
<Application.Resources>
<ResourceDictionary>
<!--Global Styles-->
...
<Color x:Key="NavbarBackground">Black</Color>
...
</ResourceDictionary>
</Application.Resources>
CustomTitleView.xaml
<ContentView>
...
<ContentView.Content>
...
<ImageButton Source="search.png" HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" BackgroundColor="{StaticResource NavbarBackground}" />
...
</ContentView.Content>
</ContentView>

If you are using separate xaml file to define resources use ResourceDictionary. If you are settings values inside App.xaml set them inside Application.Resources. Refer to docs here

Related

DataTemplateSelector not found in merged resource dictionary

I added CustomDataTemplateSelector to a ResourceDictionary in a separated file called DataTemplates.xaml which I subsequently linked in App.xaml
When I run the app, I get XamlParseException saying:
Type local:CustomDataTemplateSelector not found in xmlns clr-namespace:MyProject
On the other hand, when I put the content of DataTemplates.xaml to App.xaml, it works just fine.
App.xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary Source="../DataTemplates.xaml"/>
DataTemplates.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ResourceDictionary
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyProject">
<DataTemplate x:Key="FirstCell">
<Label Text="Some text"/>
</DataTemplate>
<DataTemplate x:Key="SecondCell">
<Label Text="Some other text"/>
</DataTemplate>
<local:CustomDataTemplateSelector
x:Key="CustomDataTemplateSelector"
SecondTemplate="{StaticResource SecondCell}"
FirstTemplate="{StaticResource FirstCell}"/>
I've confirmed the problem. (To clarify for others - the parse error occurs when attempt to run the app. During App.InitializeComponent.) I had xmlns:local ... on both App.xaml and DataTemplates.xaml.
To work-around this, use an alternative syntax for merging dictionaries, ResourceDictionary.MergedDictionaries:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
xmlns:local="clr-namespace:XFSOAnswers"
x:Class="XFSOAnswers.App">
<Application.Resources>
<ResourceDictionary>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True">
<Setter Property="ios:Page.UseSafeArea" Value="True"/>
</Style>
<ResourceDictionary.MergedDictionaries>
<local:DataTemplates />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
In case it matters, here is what I had for DataTemplates:
DataTemplates.xaml:
<?xml version="1.0" encoding="UTF-8"?>
<ResourceDictionary
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XFSOAnswers">
<DataTemplate x:Key="FirstCell">
<Label Text="Some text"/>
</DataTemplate>
<DataTemplate x:Key="SecondCell">
<Label Text="Some other text"/>
</DataTemplate>
<local:CustomDataTemplateSelector
x:Key="CustomDataTemplateSelector"
SecondTemplate="{StaticResource SecondCell}"
FirstTemplate="{StaticResource FirstCell}"/>
</ResourceDictionary>
DataTemplates.xaml.cs:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DataTemplates : ResourceDictionary
{
public DataTemplates()
{
}
}
}
(The original Source syntax should not need this .cs file. I don't know whether the syntax I used needs it or not.)

Xamarin: How to Add a Background Image to All Pages with an AspectFill property

Total newbie Xamarin user.
I'm trying to add a background image to all the pages in the mobile app.
This was a great resource: Xamarin.Forms How to add Backgroud Image on all pages in App
However, I'd like to adjust the Aspect property of the image to AspectFill, so it's not so scrunched up. This is where I'm having trouble.
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.App">
...
<Application.Resources>
<ResourceDictionary>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True" >
<Setter Property="BackgroundImageSource" Value="background_image.png" />
</Style>
...
This sets the background image. How do I adjust the Aspect property for all pages? I've tried nesting an <Image Aspect="AspectFill" /> tag within the Setter property tag, but VS gives a warning that the "property 'Value' is set more than once". Could someone help me out? I'm sure I'm making some dumb error or I've misunderstood something about Xamarin.
Thanks.
Yes, we can use the following method to set the BackgroundImageSource for all ContentPage in your app:
<Application.Resources>
<ResourceDictionary>
<Style TargetType="ContentPage" ApplyToDerivedTypes="True" >
<Setter Property="BackgroundImageSource" Value="background_image.png" />
</Style>
</ResourceDictionary>
</Application.Resources>
But we couldn't set the AspectFill property for it while Aspect is specifically a property of the Image control as jason said.
Of course,if you need a solution that allows you to change the AspectRatio and adjust the image you can use this:
<?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="Pages.PhotoPage">
<Grid >
<Image Source="background.png" Aspect="AspectFit" />
<!-- Place here the rest of the layout for the page. -->
</Grid >
</ContentPage>
Or use the solution j-petty said:
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Image AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" Source="sample.jpg" Aspect="AspectFill"/>
<StackLayout AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1,1,1,1">
<!--Content-->
<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" >
<Label x:Name="KategoriePicker" Text="Was möchtest du essen?" BackgroundColor="White" />
<Label x:Name="OrtTextBox" Text="Dein Lieferort" BackgroundColor="White" />
</StackLayout>
</StackLayout>
</AbsoluteLayout>

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 Forms Padding in StaticResource

I want to build few pages with specific Padding in sytacklayout. I do not want to wrote it in every pages. And its not good design considering if I want to change it in future. Is there a way to define padding in static resource? So that I can define it in one place App.xml and use it in other pages.
I have tried
<ContentPage.Resources>
<ResourceDictionary>
<x:String x:Key="padding">45, 0, 45, 0</x:String>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Padding="{StaticResource padding}">
<Label Text="{StaticResource padding}"/>
</StackLayout>
As said, you should use Thickness. In addition, for setting your resource at the Application level, put it in your App.xaml file:
<Application ...>
<Application.Resources>
<ResourceDictionary>
<Thickness x:Key="padding">45,0, 45, 0</Thickness>
// some others resources...
</ResourceDictionary>
</Application.Resources>
</Application>
Then call it from your different pages:
<ContentPage>
<StackLayout Padding="{StaticResource padding}">
<Label Text="{StaticResource padding}"/>
</StackLayout>
...
link to documentation
Hope it helps!
Just use Thickness instead of a string:
<ContentPage.Resources>
<ResourceDictionary>
<Thickness x:Key="padding">45,0</Thickness>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Padding="{StaticResource padding}">
<Label Text="{StaticResource padding}"/>
</StackLayout>

Xamarin: Cannot find the IValueConverter

I tried to use my custom IValueConverter which declared in the Xaml file.
The Converter Class was defined inside the EnglishKeyboard. The convert declared in a ResourceDictionary inside the xaml below. I tried to use this converter at the end of the code below
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:local="clr-namespace:ProjectorRemote"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ProjectorRemote.EnglishKeyboard"
x:Name="englishKeyboard">
<ContentView.Resources>
<ResourceDictionary>
<local:EnglishKeyboard.StringCaseConverter x:Key="caseConverter">
</local:EnglishKeyboard.StringCaseConverter>
<!-- lower 1 characters -->
<x:String x:Key="lower_1">q</x:String>
<x:String x:Key="lower1_2">w</x:String>
<x:String x:Key="lower1_3">e</x:String>
<x:String x:Key="lower1_4">r</x:String>
<x:String x:Key="lower1_5">t</x:String>
<x:String x:Key="lower1_6">y</x:String>
<x:String x:Key="lower1_7">u</x:String>
<x:String x:Key="lower1_8">i</x:String>
<x:String x:Key="lower1_9">o</x:String>
<x:String x:Key="lower1_0">p</x:String>
</ResourceDictionary>
</ContentView.Resources>
<ContentView.Content>
<StackLayout
Orientation="Vertical"
HorizontalOptions="Fill"
VerticalOptions="End">
<Grid HorizontalOptions="Center" ColumnSpacing="1">
**<local:BaseKeyView
Grid.Column="0"
Text="{StaticResource lower1_1,
Converter={StaticResource caseConverter},
ConverterParameter={Binding IsUpper}}">
</local:BaseKeyView>**
It work with no error but the converter didn't get called after I changed to the code below
<local:BaseKeyView
Grid.Column="0"
Text="{StaticResource lower1_1,
Converter={StaticResource caseConverter},
ConverterParameter={Binding IsUpper}}">
</local:BaseKeyView>
I fixed the problem by changing to this
{Binding Source={StaticResource lower1_1}, Converter={ ..... –

Resources