How to define ResourceDictionary by adding Style in Xamarin xaml {GroupStyle} - xaml

I'm trying to make something like set atribute to all labels inside a grid
I Know how to make it, just doing this:
<Grid RowSpacing="2" Padding="2,0,2,0">
<Grid.Resources>
<ResourceDictionary>
<Style BasedOn="{StaticResource Font-Awesome}" TargetType="Label"/>
</ResourceDictionary>
</Grid.Resources>
<Label Text="31 " Grid.Column="0" TextColor="#2764B5" XAlign="Start"/>
<Label Text="91 " Grid.Column="1" TextColor="#A0A1A2" XAlign="Center"/>
<Label Text="12 " Grid.Column="2" TextColor="#A0A1A2" XAlign="End"/>
</Grid>
But Its Ugly and redundant
I want to do smetthing like
<Grid RowSpacing="2" Padding="2,0,2,0" Style="{StaticResource grd-actions}">
<Label Text="31 " Grid.Column="0" TextColor="#2764B5" XAlign="Start"/>
<Label Text="91 " Grid.Column="1" TextColor="#A0A1A2" XAlign="Center"/>
<Label Text="Compartilhar " Grid.Column="2" TextColor="#A0A1A2" XAlign="End"/>
</Grid>
And On App Static Resources include the ResourceDictionary for the grid, something like:
<Style x:Key="gd-actions" TargetType="Grid">
<Setter Property="Resources">
<Setter.Value>
<ResourceDictionary>
<Style BasedOn="{StaticResource Font-Awesome}" TargetType="Label"/>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
I've being trying with a lot of ways but it's aways throw some kind of exception!
Can someone help-me Here?

I guess the most clean way to do this is by using Explicit Styles with Global Resources. Declare the style for that Labels in Application Resources and then in you label just add the Style Property:
Application:
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="xforms_test.App">
<Application.Resources>
<ResourceDictionary>
<Style x:Key="labelAquaStyle" TargetType="Label">
<Setter Property="HorizontalOptions" Value="Center" />
<Setter Property="TextColor" Value="Aqua" />
</Style>
</ResourceDictionary>
</Application.Resources>
</Application>
And in your page:
<Grid RowSpacing="2" Padding="2,0,2,0">
<Label Grid.Column="0" Text="These labels" Style="{StaticResource labelAquaStyle}" />
<Label Grid.Column="1" Text="are demonstrating" Style="{StaticResource labelAquaStyle}" />
<Label Grid.Column="2" Text="explicit styles" Style="{StaticResource labelAquaStyle}" />
</Grid>

Related

.NET MAUI set focus to control into ControlTemplate

I have this ControlTemplate (two controls on it):
<Style TargetType="controls:QuickSearch">
<Setter Property="ControlTemplate">
<Setter.Value>
<ControlTemplate>
<VerticalStackLayout HorizontalOptions="Fill">
<Entry
x:Name="EntryFilter"
Text="{TemplateBinding Filter}"
Completed="Entry_Completed"
behaviors:SetFocusOnEntryCompletedBehavior.NextElement="{x:Reference LstResults}"
Focused="Entry_Focused"
ClearButtonVisibility="WhileEditing"
Placeholder="{TemplateBinding PlaceHolder,Mode=TwoWay}">
<Entry.Triggers>
<EventTrigger Event="Completed">
</EventTrigger>
</Entry.Triggers>
</Entry>
<ListView
x:Name="LstResults"
Margin="5"
Background="{DynamicResource PN_ColorFondoPrimario}"
ZIndex="999"
ItemsSource="{TemplateBinding Results}"
SelectionMode="Single"
SelectedItem="{TemplateBinding SelectedItem,Mode=TwoWay}"
IsVisible="{TemplateBinding PerforminigSearch}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding DisplayField}" Margin="9"/>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.Triggers>
</ListView.Triggers>
</ListView>
</VerticalStackLayout>
<-- MAUI don't allow to set triggers here -->
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
<-- ======================================= -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I want to set the focus into EntryFilter when my control template receives focus. I was trying with a trigger, but MAUI doesn't allow me to put some triggers into the <ControlTemplate> tag.
<Style TargetType="controls:QuickSearch">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="EntryFilter" Property="IsFocused" Value="True"/>
</Trigger>
</Style.Triggers>
. . . .
. . . .
</Style>
I tried with MAUI toolkit, but where should I put SetFocusOnEntryCompletedBehavior?

Can Maui configure a shadow in a line?

I´m developing an app in .net maui and i have a question i have not answered myself through browsing.
I'm trying to apply a shadow to a border and the following code works perfectly.
<Border
Style="{StaticResource light-theme-border}"
Grid.Column="1"
Grid.Row="3"
Grid.ColumnSpan="7">
<Border.Shadow>
<Shadow
Brush="red"
Offset="1,11"
Radius="20"
Opacity="0.25"/>
</Border.Shadow>
</Border>
But when i write shadow directly inside the border properties it catches the property but i don't know how to dump the [brush, offset, radius & opacity] info:
<Border
Style="{StaticResource light-theme-border}"
Grid.Column="1"
Grid.Row="3"
Grid.ColumnSpan="7"
Shadow="???????????????????????????">
</Border>
You can then define and consume it as a resource (same what you did with Style property):
<ContentPage.Resources>
<ResourceDictionary>
<Shadow
x:Key="CommonShadow"
Brush="red"
Offset="1,11"
Radius="20"
Opacity="0.25"/>
<Border
Style="{StaticResource light-theme-border}"
Grid.Column="1"
Grid.Row="3"
Grid.ColumnSpan="7"
Shadow="{StaticResource CommonShadow}">
</Border>
Or integrate it in your existing style of Border
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="light-theme-border" TargetType="Border">
<Setter Property="WidthRequest" Value="20" />
<Setter Property="Shadow">
<Setter.Value>
<Shadow
Brush="red"
Opacity="1"
Radius="50"
Offset="20,20" />
</Setter.Value>
</Setter>
</Style>
<Border
Style="{StaticResource light-theme-border}"
Grid.Column="1"
Grid.Row="3"
Grid.ColumnSpan="7">
</Border>
Or integrate it in your existing style of Border as a static resource
<ContentPage.Resources>
<ResourceDictionary>
<Shadow
x:Key="CommonShadow"
Brush="red"
Offset="1,11"
Radius="20"
Opacity="0.25"/>
<Style x:Key="light-theme-border" TargetType="Border">
<Setter Property="WidthRequest" Value="20" />
<Setter Property="Shadow" Value="{StaticResource CommonShadow}"/>
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<Border
Style="{StaticResource light-theme-border}"
Grid.Column="1"
Grid.Row="3"
Grid.ColumnSpan="7">
</Border>

Change Image with trigger in xaml based on boolean

Hey I am trying to show different pictures based on boolean values with triggers, I have one image a simple where it shows the green one when it is true, that works but wiht the triggers, I get an empty unhandled exception.
What am I missing?
Thanks
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Content}" FontSize="26"></Label>
<Image Source="green.png" HorizontalOptions="EndAndExpand" Aspect="AspectFit" IsVisible="{Binding Done}"></Image>
<Image>
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Done}" Value="false">
<Setter Property="Source" Value="red.png"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Done}" Value="true">
<Setter Property="Source" Value="green.png"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

How Can I Reuse an Icon in Resources in UWP? In WPF, I'd use x:Shared=false

I am trying to create a button Style that I can use for a "Lookup" button throughout my UWP app. However, the icon only appears on the first button on the screen. I tried this solution using templates, but it is not working for me. Thanks for the help.
Code:
<Page.Resources>
<ControlTemplate x:Key="FindSymbolTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</ControlTemplate>
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content">
<Setter.Value>
<ContentControl Template="{StaticResource FindSymbolTemplate}" />
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
....
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
....
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
The two buttons in the UI. Only the first has the SymbolIcon content.
#Romasz's solution absolutely works, but what if you want a lightly different Foreground on the SymbolIcon inside another Button?
Here's a potentially more flexible way that I normally go with.
First let's create a base Style that holds some default values for all the icons.
<Style x:Key="Style-Icon-Base"
TargetType="ContentControl">
<!-- If you don't specify the Foreground, it will use its ancestor's -->
<!--<Setter Property="Foreground"
Value="White" />-->
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Width"
Value="20" />
<Setter Property="Height"
Value="20" />
<Setter Property="Padding"
Value="0" />
</Style>
Then we create a new icon Style which inherits from the one above. Note within the ControlTemplate I have used TemplateBinding to make property values dynamic. TemplateBinding isn't available inside a DataTemplate.
<Style x:Key="Style-Icon-Find"
BasedOn="{StaticResource Style-Icon-Base}"
TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<!--
'cause you cannot change the size of the SymbolIcon, we insert a Viewbox here,
otherwise you don't need it.
-->
<Viewbox Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<SymbolIcon Symbol="Find"
Foreground="{TemplateBinding Foreground}" />
</Viewbox>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This way you have created a highly reusable icon Style, to use it, have a look at the following Buttons:
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Margin="4"
Padding="8"
BorderBrush="LightBlue">
<ContentControl Width="36"
Height="36"
Foreground="DarkCyan"
Style="{StaticResource Style-Icon-Find}" />
</Button>
<!-- Note how I defined the Foreground at the Button level and it flows down to the icon -->
<Button Foreground="DarkGoldenrod"
Margin="4">
<StackPanel Orientation="Horizontal">
<ContentControl Style="{StaticResource Style-Icon-Find}"
Width="16"
Height="16" />
<TextBlock Text="Search"
VerticalAlignment="Center"
Margin="8,0,0,0" />
</StackPanel>
</Button>
<Button Margin="4"
Padding="4">
<ContentControl Style="{StaticResource Style-Icon-Find}" />
</Button>
</StackPanel>
And they look like:
Generally UI elements can be used once (or saying different - have only one parent) - this is probably why it only works for the first button in your case. One solution may be to define DataTemplate and use it as ContentTemplate, so each button creates its own icon:
<Page.Resources>
<DataTemplate x:Key="FindTemplate">
<SymbolIcon Symbol="Find" Foreground="White" />
</DataTemplate>
</Page.Resources>
...
<Button x:Name="tourNumLookup" ContentTemplate="{StaticResource FindTemplate}"
Grid.Column="1" Margin="10,0" VerticalAlignment="Center" />
<Button x:Name="customerIdLookup" ContentTemplate="{StaticResource FindTemplate}"
VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Margin="10,0" />
You don't need to create ControlTemplate to reuse the icon. You can simply put this SymbolIcon to the resource dictionary and use as StaticResource for the buttons' Content.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
</Page.Resources>
<Button x:Name="tourNumLookup"
Content="{StaticResource FindSymbol}"
Grid.Column="1"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Content="{StaticResource FindSymbol}"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Row="1"
Margin="10,0" />
UPDATE
BTW this is possibly a bug in the UWP platform, because I tried the following code and only the first Button rendered the icon at desing time and none of the at runtime.
<Page.Resources>
<SymbolIcon x:Key="FindSymbol" Symbol="Find" Foreground="White" />
<Style TargetType="Button" x:Key="LookupButton">
<Setter Property="Content" Value="{StaticResource FindSymbol}"/>
</Style>
</Page.Resources>
<StackPanel>
<Button x:Name="tourNumLookup"
Style="{StaticResource LookupButton}"
Margin="10,0"
VerticalAlignment="Center" />
<Button x:Name="customerIdLookup"
Style="{StaticResource LookupButton}"
VerticalAlignment="Center"
Margin="10,0" />
</StackPanel>
I tried to assign the Setter's Value directly but I got the same result. And also tried with FontIcon.

How to call a Style in a ResourceDictionary file in XAML?

I have a button style in a created style.xaml ResourceDictionary file.
I used this code to call it:
<Button Style="{DynamicResource exitButton}" />
But it didn't recognize the style key either using StaticResource doesn't work too. How to solve this problem?
My style code:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="exitButton" TargetType="Button">
<Setter Property="Width" Value="22"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Background" Value="#FF7070"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock Text="X"
FontSize="15"
Foreground="White"
FontWeight="Bold"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
You have to import the ResourceDictionary file in your xaml, in the Resources tags.
Something like this:
<UserControl blablabla...>
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/*PROJECT_NAME*;component/*FOLDER_PATH*/style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</USerControl.Resources>
<!-- the content -->
...
<Button Style="{StaticResource exitButton}"/>
</UserControl>
You have two options:
As HasNotifications said, embede the resource into the view that you want the style take affect
Embed the style to the application ResourceDictionary. On that case the style will be available to any view on the application
Add the following code to the App.xaml file:
<Application x:Class="WpfApp1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/*PROJECT_NAME*;component/*FOLDER_PATH*/style.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>