Use AppThemeBinding not specifying everywhere dark and light values? - xamarin

I'm curious is there more convenient way to use themes in Xamarin forms.
Known way is add Colors into ResourceDictionary in App.xaml:
<Color x:Key="BackgroundColorDark">#111111</Color>
<Color x:Key="BackgroundColorLight">#ffffff</Color>
and then specify it on element like this:
<Button BackgroundColor="{AppThemeBinding Light={StaticResource DarkPageBackgroundColor},
Dark={StaticResource LightPageBackgroundColor}}" ... >
So my question is there possibility to do it in different way? I have reaaly lots of buttons for example, and I don't want to specify everywhere for each of those buttons that it has to use this color for light theme and that for dark. I want to specify it like: Hey Button, your background color is "ButtonBackgroundColor" and its value depends on current theme, which itself is set in two different ResourceDictionaries, like this:
<ResourceDictionary x:Name="Dark">
<Color x:Key="ButtonBackgroundColor">#000000</Color>
</ResourceDictionary>
<ResourceDictionary x:Name="White">
<Color x:Key="ButtonBackgroundColor">#ffffff</Color>
</ResourceDictionary>

You can use a ButtonStyle for different Buttons
<Color x:Key="LightPrimaryColor">WhiteSmoke</Color>
<Color x:Key="LightSecondaryColor">Black</Color>
<!-- Dark colors -->
<Color x:Key="DarkPrimaryColor">Teal</Color>
<Color x:Key="DarkSecondaryColor">White</Color>
<Style x:Key="ButtonStyle"
TargetType="Button">
<Setter Property="BackgroundColor"
Value="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}" />
<Setter Property="TextColor"
Value="{AppThemeBinding Light={StaticResource LightSecondaryColor}, Dark={StaticResource DarkSecondaryColor}}" />
</Style>
And in Xaml for a Button add Style
<Button Text="MORE INFO"
Style="{StaticResource ButtonStyle}" />
Info here https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/theming/system-theme-changes
I use ButtonStyle and made one ButtonStyleA for other Buttons that i want to show in an other way

The answer from Bas H is correct. You should use styles in most scenarios. You can also even use style implicitly, meaning they will be applied by default on all controls of the target type.
<Style TargetType="Button">
<Setter Property="BackgroundColor"
Value="{AppThemeBinding Light={StaticResource LightPrimaryColor}, Dark={StaticResource DarkPrimaryColor}}" />
<Setter Property="TextColor"
Value="{AppThemeBinding Light={StaticResource LightSecondaryColor}, Dark={StaticResource DarkSecondaryColor}}" />
</Style>
// The backgroundcolor and textcolor are applied by default now.
<Button Text="MORE INFO"/>

Agree with comments above, think that most people miss that you can bind to static colours within the style inside the resource dictionary. Very useful when you want to change theme colours, one up is apples to all styles.
I do this but I also allow users to choose colours which i save in a database column, onload of the app I'll set the value in the resource dictionary in code ;)

Related

How to set Navigation text color in Xamarin.Forms when using Shell

In my AppShell.xaml I have a number of settings for UI themes.
For example,
<Setter Property="Shell.BackgroundColor" Value="Blue" />
<Setter Property="Shell.TitleColor" Value="White" />
However, I can't find the Shell setting for the text which appears next to the <- (Back) button in iOS.
I've tried setting this using the NavigationPage object, but that had no effect.
How can this be set? Thanks.
EDIT: See my own answer/solution below.
I have found the solution.
What controls the Back button color is the ForegroundColor setter.
For example:
<Setter Property="Shell.ForegroundColor" Value="White" />

Include controls in a ControlTemplate from another .xaml

I want to create a control which displays an image and a watermark (image or something else) on it.
But the watermark should be loaded from another XAML file in order to let people custom the way the watermark will appear : alignment, opacity, size, nature of the watermark (TextBlock, Image, ...).
For instance I could load my watermark with this appearance
<Border BorderThickness="5" BorderBrush="Aqua" Width="50" Height="50">
<Image Source="play.png" />
</Border>
This code is from my Themes/generic.xaml and MyWatermarkControl (inherits from Control) is the class which contain the code of the control (dependency properties).
<Style TargetType="local:MyWatermarkControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:MyWatermarkControl">
<Grid>
<Image Source="{TemplateBinding ImagePath}" />
<Image x:name="watermark" Source="play.png" /> <!--I want this to be loaded from another .xaml-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My search results lead me to add in my ControlTemplate stuff like ContentPresenter, ContentTemplate, DataTemplate : so many results and I cannot understand how do they work but the fact they are nested
You can add a Source property to your MyWatermarkControl then bind the Source property of your embedded Image to this property. For more details see the following tutorial that I wrote:
A Simple Pattern for Creating Re-useable UserControls in WPF / Silverlight

Windows phone page styling

I have a few pages and want that they use one style. See in images, for example. as you can see all three pages have static styled header. So how i can do it?
Sorry if the question is easy, it's in the evening and i can't think very clear, and been working really hard...
I tried setting Template, but i keep getting an exception, that i cannot use templating for UserControl...
Why can't using like following?
<phone:PhoneApplicationPage.Style>
<Style TargetType="phone:PhoneApplicationPage">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="phone:PhoneApplicationFrame">
<StackPanel Background="Black">
<Border Height="100" Width="100" Background="Red"/>
<ContentPresenter />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</phone:PhoneApplicationPage.Style>
You could create a UserControl that includes a StackPanel, with a horizontal orientation, then add two controls inside the StackPanel, maybe an Image and a TextBlock, add margins as required, add colours as required. Once your UserControl is defined, add this UserControl to all the pages what you want to have the same look and feel. You might even be able to move this UserControl to a base page and derive your pages from this base page.
Hope this helps.

WP7 creating FontFamily and default colors as Static Resource

I would like to setup some default fonts as static resource within my App. Similarly with some colors.
Do I just use a string (defined as an applicationResource (in App.xaml) or can I actually define a FontFamily and a Color within here.
thanks
You could define an implicit style to set a default color and font family to use for all TextBlocks like this:
<Application.Resources>
<ResourceDictionary>
<Color x:Key="MySpecialColor">#F4811F</Color>
<SolidColorBrush x:Key="MySpecialColor" Color="{StaticResource MySpecialColor}" />
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource MySpecialColorBrush}" />
<Setter Property="FontFamily" Value="Comic Sans" />
</Style>
</ResourceDictionary>
</Application.Resources>
You could then adjust as necessary for specific TextBlocks and add implict styles for other controls if you need to.
Read more at http://www.windowsphonegeek.com/articles/Windows-Phone-7-Mango-Implicit-Styles
You can also use the color or the brush as you need elsewhere, either in XAML or code:
(Color)App.Current.Resources["MySpecialColor"];

Event to Command in a style

Can someone tell me how to code an event to command in a style for a tabitem? I have no problems using it elsewhere but I can not figure it out for a style.
I am trying to do this in Xaml for WPF using MVVM-Light toolkit.
Here is an example of what I am trying to do:
<DataTemplate x:Key="WorkspacesTemplate">
<igWindows:XamTabControl
AllowTabClosing="True"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding}" TabItemCloseButtonVisibility="Visible"
Margin="4"
Theme="Office2k7Black" >
<igWindows:XamTabControl.Resources>
<Style TargetType="{x:Type igWindows:TabItemEx}"
BasedOn="{StaticResource {x:Type igWindows:TabItemEx}}" >
<Setter Property="Header" Value="{Binding Path=DisplayName}" />
<Style.Triggers>
<i:EventTrigger >
<cmd:EventToCommand Command="{Binding Path=CloseCommand}" />
</i:EventTrigger>
</Style.Triggers>
</Style>
</igWindows:XamTabControl.Resources>
</igWindows:XamTabControl>
</DataTemplate>
I am using an infragistics TabControl but it shouldnt be much different than a regular tab control.
In your example, you don't have an EventName attribute in the EventTrigger element. You need to specify an event on the tab that you want to trigger the command.

Resources