Windows Store app's overriden resource value ignored in template - xaml

I'm creating a Windows Store app where each page has a dominant color used for titles, buttons and such.
In App.xaml I've created a default Brush that's overriden in each Page's xaml file, and a style template for Buttons which I reuse in every page. The templates are supposed to use the page's color but for some reason they stick with the default value.
Here are my xaml files.
App.xaml
<Application
x:Class="Foo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Foo"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<SolidColorBrush x:Name="SectionDefaultBrush" Color="Red" />
<Style TargetType="Button" x:Name="NavigationButtonStyle">
<Setter Property="FontFamily" Value="Myriad Pro" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Rectangle x:Name="Border" Fill="#f4f4f4" Margin="0" />
<TextBlock Foreground="{ ThemeResource SectionDefaultBrush }" Text=">" FontSize="31" />
<ContentPresenter x:Name="Content" VerticalAlignment="Center" Foreground="#5A5A5A" HorizontalAlignment="Left" FontSize="31"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
SomePage.xaml
<Page
x:Class="Foo.Pages.SomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<SolidColorBrush x:Key="SectionDefaultBrush" Color="Green" />
</Page.Resources>
<ViewBox>
<Canvas>
<TextBlock Text="Some text" Foreground="{ ThemeResource SectionDefaultBrush }" Canvas.Left="130" TextWrapping="Wrap" Canvas.Top="252" Height="177" Width="507" FontFamily="Myriad Pro" FontSize="54" />
<Button Content="Click me" Style="{ ThemeResource NavigationButtonStyle }" Canvas.Left="130" Canvas.Top="900" Width="507" Height="48" />
</Canvas>
<ViewBox>
In this example, the TextBlock's text color is green as expected (and red if I remove the Brush from Page.Resources), but the Button's content remains red. Is there a way to tell the template to use the final color ?

The app's resource dictionary doesn't know about other dictionaries and unlike with WPF's DynamicResources - StaticResource isn't reevaluated and ThemeResource is, but I think only when the actual theme changes. The way you can customize the color of that button is to use TemplateBinding in the template and bind to say the Foreground property of the button and also set that in the Foreground Setter of your button style to {StaticResource SectionDefaultBrush}. Then in your page you can override that by setting the Foreground of the button to a different value or using a derived button style that changes the Foreground value.
Ideally too - you should define theme resources in your dictionary so the brushes change depending on OS theme (especially high contrast). You might want to name your brush then as "SectionDefaultThemeBrush" instead of just "SectionDefaultBrush".

Related

UWP ListView selected item highlight disappears if ItemContainerStyle is set

I am using a ListView to display a list of items. But when I set the font of the items using ItemContainerStyle and now an item is selected, the ListView highlight (blue line on the left) is no longer visible. On this screenshot here is a comparison. The problem has come with the installation of the Microsoft.UI.Xaml package, because here the design of ListView has been changed. Is there any way to fix this without having to remove ItemContainerStyle or the Microsoft.UI.Xaml package?
MainPage.xaml
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ListView HorizontalAlignment="Left">
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234"/>
</ListView>
<ListView HorizontalAlignment="Right">
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234"/>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</Grid>
</Page>
App.xaml
<Application
x:Class="App1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1">
<Application.Resources>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
</Application.Resources>
</Application>
The reason for this behavior is that when you set a new ItemContainerStyle for the listview, it overrides the default item style that is used from the WinUI library.
The solution to this is that you need to give the item a style based on the style that the item is currently using. I find the default style of the ListViewItem in WinUI GitHub: ListViewItem_themeresources. So you just need to create a style that is based on the DefaultListViewItemStyle.
You will need to change a little bit of your code like this:
<ListView>
<ListViewItem Content="ABCD"/>
<ListViewItem Content="abcd"/>
<ListViewItem Content="1234" />
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem" BasedOn="{StaticResource DefaultListViewItemStyle}">
<Setter Property="FontSize" Value="25"></Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>

Effect on all buttons in Xamarin Forms

I'm trying to have a effect on all my buttons, but I can't seem to get the configuration right.
this is what I have now:
<ResourceDictionary>
<ControlTemplate x:Key="ButtonTemplate" >
<Grid RowSpacing="0" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<ContentPresenter Grid.Row="0" Grid.Column="0" >
<ContentPresenter.Effects>
<effects:ShadowEffect Radius="5" DistanceX="5" DistanceY="5">
<effects:ShadowEffect.Color>
<OnPlatform x:TypeArguments="Color">
<On Platform="iOS" Value="Black" />
<On Platform="Android" Value="White" />
<On Platform="UWP" Value="Red" />
</OnPlatform>
</effects:ShadowEffect.Color>
</effects:ShadowEffect>
</ContentPresenter.Effects>
</ContentPresenter>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type Button}">
<Setter Property="ControlTemplate" Value="{StaticResource ButtonTemplate}"></Setter>
</Style>
</ResourceDictionary>
But this throws a Can't resolve ControlTemplateProperty on Button.
Anybody has any idea on how to do this?
As you can see at Xamarin.Forms Guides the Control Templates isn't applicable to Button.
A ControlTemplate can be applied to the following types by setting
their ControlTemplate properties:
ContentPage
ContentView
TemplatedPage
TemplatedView
The error Can't resolve ControlTemplateProperty on Button make sense. Button inherites from View, not TemplatedView as would be needed.
So about your main point, effects cann't consumed directly by style, but you can achieve this thru attached properties. Here is some good references to you:
How to create an effect
How to consume it with styles
A good example
I hope it help you (and sorry for my bad english)

why ButtonPressedBackgroundThemeBrush is not working for button

Whenever I press and hold the button I can see a blue color background till I release the button
I tried to reset it white by using the key ButtonPressedBackgroundThemeBrush
Here is my button code
<Button Content="Submit" BorderThickness="0" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" FontSize="21" Height="85" BorderBrush="White" Command="{Binding testCommand}" Foreground="{StaticResource Green}">
<Button.Resources>
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="White" />
</Button.Resources>
</Button>
But its not working for some reason.
Try defining the brush in your application resources:
<Application.Resources>
<SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="White" />
</Application.Resources>
This will change the button press background for ALL buttons however. If you want specific buttons to have different backgrounds, you'll need to edit the Button template for each. One simple way to do that is to define a style for each and set the Background to whatever you like during the IsPressed Trigger
<Button>
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

Xamarin UWP custom CommandBar

I'd like to create a custom CommandBar for the UWP part of my Xamarin project.
I want to make a logo on a background color. The only way to get this, is making a visualbrush or grid, to contain both the background color and the picture.
I've read it can be done like so;
<Window.Resources>
<VisualBrush x:Key="myBrush">
<VisualBrush.Visual>
<Grid>
<Rectangle Fill="Red" />
<Image Source="troll.png" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Window.Resources>
I need to add this commandbar during runtime like so:
var _globalAppBar = new CommandBar();
_globalAppBar.Background = [Link to above layout]
Questions:
How or where can I add this in my Xamarin UWP project? Add a XAML file?
How can I link during run time to the layout? Or is there a better way to do this?
Ideally, you would create a new style for the CommandBar and add it to the App.xaml resource dictionary
<Application.Resources>
<Style TargetType="CommandBar">
<Setter Property="Background">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<Grid>
<Rectangle Fill="Red" />
<Image Source="troll.png" />
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
because the style has no key, it will become the implicit style for CommandBar and therefore be applied to all CommandBar instances

Xaml BackGround Image

I am writing my first Win 8.1 App and I am trying to set background image for Hubapp Layout.
I can see the background in the preview, but once I run the application it became black background.
Here is my code:
<Grid x:Name="LayoutRoot">
<Hub x:Name="Hub" x:Uid="Hub" Header="The Header">
<Hub.Background>
<ImageBrush Stretch="None"
ImageSource="Assets\background.png"
AlignmentY="Top" AlignmentX="Center"/>
</Hub.Background>
</Hub>
</Grid>
I tried also to set the background using ThemeResource but I got the same result only black background
<Grid x:Name="LayoutRoot">
<Hub x:Name="Hub" x:Uid="Hub" Header="The Header">
Background="{ThemeResource HubBackgroundImageBrush}"> </Hub>
</Grid>
here is the Resources code
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<ImageBrush x:Key="HubBackgroundImageBrush" ImageSource="Assets\background.png"/>
</ResourceDictionary>
<ResourceDictionary x:Key="HighContrast">
<ImageBrush x:Key="HubBackgroundImageBrush" ImageSource="{x:Null}"/>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
Would you please tell what is wrong?
Just looked into this and it appears the background of the hub doesn't appear until a HubSection is added.
If I try
<Hub x:Name="hub" Background="Red">
</Hub>
No Background appears despite the Hub appearing to stretch to the whole screen
but if I add a HubSection
<Hub x:Name="hub" Background="Red">
<HubSection></HubSection>
</Hub>
Red Background appears.