Applying different style to same control inside different containers - xaml

Is this possible using Xaml? For example, I have labels inside group boxes and toolbars. I have set labels' foreground color to white using Style in Xaml code.
Background color of the window is black so the group boxes have this background, as well. However, toolbar's background color is System.Media.Colors.Control (or whatever it is by default) and I'd like to keep it that way. The problem is that white isn't the best color on almost white (toolbar).
Is it possible to set Label's foreground color to be different depending on what its container is? And only in one place - in my case inside main window's Window.Resources tag.
Something like this:
<Style TargetType="Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White"/>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ToolBar.Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="Black"/>
</Setter.Value>
</Setter>
</Style>
Thanks,
J.

You can define the resources with the control e.g.
<ToolBar>
<ToolBar.Resources>
<Style TargetType="Label">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="White"/>
</Setter.Value>
</Setter>
</Style>
</ToolBar.Resources>
</ToolBar>
Then labels in your tool bar will pick the local resource.

Related

ThemeResource in Style isn't used when I build my UWP app

I am trying to make a rectangle that changes color after a tapped event. It should cycle between a disabled mode (gray) and the accent color. I am trying to do this using styles. When I use (a shade of) the accent color in the XAML code {ThemeResource SystemControlHighlightAltListAccentHighBrush} it correctly shows the accent color. It also shows the correct colors in the designer (Visual Studio). However, if I use the theme colors in a resource dictionary, it replaces them by grayish or no colors in my app (after build). This is my ResourceDictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:I_have_never">
<!--Disabled-->
<Style TargetType="RelativePanel" x:Key="Disabled">
<Setter Property="Tag">
<Setter.Value>0</Setter.Value>
</Setter>
<Setter Property="Margin">
<Setter.Value>30,15,30,15</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>{ThemeResource SystemControlBackgroundListLowBrush} </Setter.Value>
</Setter>
</Style>
<!--Enabled-->
<Style TargetType="RelativePanel" x:Key="Enabled">
<Setter Property="Tag">
<Setter.Value>2</Setter.Value>
</Setter>
<Setter Property="Margin">
<Setter.Value>30,15,30,15</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>{ThemeResource SystemControlHighlightAltListAccentHighBrush}</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
This is my XAML code:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="150" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<RelativePanel Name="Category1"
Grid.Row="0"
Grid.Column="0"
Tapped="ToggleStatus"
Style="{StaticResource Enabled}">
</RelativePanel>
</Grid>
And this is my C# code to toggle between the styles:
private void ToggleStatus(object sender, RoutedEventArgs e)
{
RelativePanel panel = sender as RelativePanel;
if ((string)panel.Tag == "0")
{
panel.Style = (Style)App.Current.Resources["Enabled"]; // Tag = 1
}
else if ((string)panel.Tag == "1")
{
panel.Style = (Style)App.Current.Resources["Disabled"]; // Tag = 2
}
}
In the design view this works great. It nicely shows the grey or accent color backgrounds. However, when I build this, no colors are shown.
It does show colors as long as I use real colors (e.g. Gray) instead of the ThemeResource. It also works if I use the ThemeResource straight in the XAML code (no styles). Why does it only work in the designer? Why does it not work if I use the ThemeResource in the styles? And how could I fix this?
Why does it not work if I use the ThemeResource in the styles? And how could I fix this?
You are using XAML Property Element Usage Syntax to set the extensionUsage (i.e. {ThemeResource} or {StaticResource}) to Setter.Value property in the styles:
<Setter ...>
<Setter.Value>
objectValue
</Setter.Value>
</Setter>
According to the Syntax part of the official documentation Setter.Value property, when setting an extensionUsage (i.e. {ThemeResource} or {StaticResource}) to Setter.Value property in the styles, we should use XAML Attribute Usage Syntax instead of using XAML Property Element Usage Syntax:
<Setter Property="propertyName" Value="extensionUsage"/>
So you should use the following code to set the Background with {ThemeResource} in the styles:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ThemeResourceInStyle">
<!--Disabled-->
<Style TargetType="RelativePanel" x:Key="Disabled">
<Setter Property="Tag">
<Setter.Value>0</Setter.Value>
</Setter>
<Setter Property="Margin">
<Setter.Value>30,15,30,15</Setter.Value>
</Setter>
<!--use XAML Attribute Usage Syntax to set extensionUsage -->
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundListLowBrush}" />
</Style>
<!--Enabled-->
<Style TargetType="RelativePanel" x:Key="Enabled">
<Setter Property="Tag">
<Setter.Value>1</Setter.Value>
</Setter>
<Setter Property="Margin">
<Setter.Value>30,15,30,15</Setter.Value>
</Setter>
<!--use XAML Attribute Usage Syntax to set extensionUsage -->
<Setter Property="Background" Value="{ThemeResource SystemControlHighlightAltListAccentHighBrush}" />
</Style>
</ResourceDictionary>

Use your own image for thumb in slider

I would like to use my own image for the thumb in Slider. A have created a copy of standard style for slider in Blend and change the thumb section:
<Style x:Key="SliderThumbStyle" TargetType="Thumb">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Thumb">
<Image Source="Assets/Logo.png" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It works, but image is embedded in the line of slider:
I want to set image size (for example 100x100), so the part of image will be above the slider line.
Is it possible ?

How to set HubSection Header Style

I want to change Font Family, Font Size and Foreground color for HubSection Header.
Something like this:
<Style TargetType="HubSection" x:Key="HubSection">
<Setter Property="Header">
<Setter.Value>
<Setter Property="FontSize" Value="100"></Setter>
<Setter Property="Foreground" Value="Yellow"></Setter>
</Setter.Value>
</Setter>
</Style>
<HubSection Width="500" Header="Section Name" Style="{StaticResource HubSection}">
How can I do it?
The property you want to change isn't Header but HeaderTemplate. Here's my working example:
<Style TargetType="HubSection">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding}"
FontSize="100"
Foreground="Yellow"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
If you want to apply this style to all Hub controls in your app, just remove the Key and place it in the App.xaml file in Resources.
If you don't want to override header template you can override default theme resources:
<FontWeight x:Key="HubSectionHeaderThemeFontWeight">SemiLight</FontWeight>
<x:Double x:Key="HubSectionHeaderThemeFontSize">26.667</x:Double>
Unfortunately there is no special resources for FontFamily and Foreground. Template is using defaults from Button. So you will influence whole application. But in many cases that's what you want, right?
<FontFamily x:Key="ContentControlThemeFontFamily">Segoe UI</FontFamily>
<SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="Red" />

How to set page background in metro application

I have strange problem. I can't set background for my page in metro app.
Below is a simple view of my xaml structure
<Page Background="White">
<ListView Background="Red">
</ListView>
</Page>
The problem is that the background of the page is black. So I have red rectangle (ListView area) set on black background. I want my page to be white. I saw few examples and it seems that I did good. I've also tried with brushes but same result.
If you want your app to have a white background on all pages, then the easiest way to achieve this is to set the RequestedTheme on Light in the App.xaml file. This will not only give you a white background, but it will automatically change all other colors too, like the foreground color (for text etc.) will be black by default.
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
...
RequestedTheme="Light">
For a single page I've always used a grid as rootcontainer in a page and that worked fine:
<common:LayoutAwarePage
x:Name="pageRoot"
...
>
<Grid Background="White">
Note that if you want to use an image as background instead of a color, you'll have to work with attached properties:
<Grid>
<Grid.Background>
<ImageBrush x:Name="backgroundGrid" ImageSource="/Assets/Paper.jpg" />
</Grid.Background>
I think the issue you're running into is that the default style for the page is overriding your attempt to set the background color.
If you look at the file StandardStyles.xaml, it includes a LayoutRootStyle (at the very end of the file). If you change the Value from the default to a hex color value (for example, #FFFF0000 would give you red), the background of the app will be changed correspondingly. This is a simple way to do what you want, but may not be a best practice.
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="{StaticResource ApplicationPageBackgroundThemeBrush}"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
Alternatively, you could set the background for the root Grid element, which would give you more granular control. Or you could create a custom style that overrides LayoutRootStyle in your page's Page.Resources section, by copying the rule into that section, and then modifying the Value of the Background setter.
Here's what it should look like:
<Page.Resources>
<Style x:Key="LayoutRootStyle" TargetType="Panel">
<Setter Property="Background" Value="#FFFF0000"/>
<Setter Property="ChildrenTransitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
Hope that helps.

Remove Stagger in Silverlight Chart X-Axis Labels

I created a Silverlight Column chart and rotated the X-Axis, following the guidelines of this MSDN Blog. The labels are rotated correctly, but I end up with staggered labels in my X-Axis, which does not fit well. I would like to remove the stagger from the labels.
Here is the XAML:
<toolkit:Chart Name="theColumnChart" BorderThickness="0" Margin="5"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource Chart}"
Template="{StaticResource ChartTemplate}" TitleStyle="{StaticResource ChartTitleStyle}">
<toolkit:Chart.Palette>
<visualizationToolkit:ResourceDictionaryCollection>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint" BasedOn="{StaticResource ColumnDataPointStyle}">
<Setter Property="Background" Value="Goldenrod"/>
</Style>
</ResourceDictionary>
<ResourceDictionary>
<Style x:Key="DataPointStyle" TargetType="toolkit:ColumnDataPoint" BasedOn="{StaticResource ColumnDataPointStyle}">
<Setter Property="Background" Value="SaddleBrown"/>
</Style>
</ResourceDictionary>
</visualizationToolkit:ResourceDictionaryCollection>
</toolkit:Chart.Palette>
<toolkit:Chart.Axes>
<toolkit:LinearAxis Minimum="0" Orientation="Y" />
</toolkit:Chart.Axes>
<toolkit:Chart.Series>
<toolkit:ColumnSeries DependentValueBinding="{Binding ItemValue}" IndependentValueBinding="{Binding ItemKey}"
ItemsSource="{Binding Statistics1}" Title="{Binding SeriesTitle}">
<toolkit:ColumnSeries.IndependentAxis>
<toolkit:CategoryAxis Orientation="X">
<toolkit:CategoryAxis.AxisLabelStyle>
<Style TargetType="toolkit:AxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:AxisLabel">
<layout:LayoutTransformer>
<layout:LayoutTransformer.LayoutTransform>
<RotateTransform Angle="-45"/>
</layout:LayoutTransformer.LayoutTransform>
<TextBlock Text="{TemplateBinding FormattedContent}"/>
</layout:LayoutTransformer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:CategoryAxis.AxisLabelStyle>
</toolkit:CategoryAxis>
</toolkit:ColumnSeries.IndependentAxis>
</toolkit:ColumnSeries>
</toolkit:Chart.Series>
</toolkit:Chart>
Here is a picture of the problem:
When the labels are rotated by 90°, even with visually sufficient space between them, the stagger occurs, not sure why. So I end up with vertical staggered labels with plenty of space between them!
I came across the problem today, and I found a slightly hacky solution which does not require the modification of the control itself, but only involves a custom control template.
The following code shows the date labels vertically, and remove the stagger.
Every label is wrapped into a Canvas, which, as explained here, does not clip its content.
I had to modify the labels' margins to align them with axis marks.
<toolkit:DateTimeAxis.AxisLabelStyle>
<Style TargetType="toolkit:DateTimeAxisLabel">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="toolkit:DateTimeAxisLabel">
<Canvas Height="55">
<sdk:Label Content="{Binding StringFormat=\{0:dd/MM/yyyy\}}" Margin="-30,30,0,0" >
<sdk:Label.RenderTransform>
<RotateTransform Angle="-90" />
</sdk:Label.RenderTransform>
<sdk:Label.RenderTransformOrigin>
<Point>0.5, 0.5</Point>
</sdk:Label.RenderTransformOrigin>
</sdk:Label>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</toolkit:DateTimeAxis.AxisLabelStyle>
here is the result:
Rachel Martin,
The labels above are still wide enough that there's not enough room to fit them all next to each other. You could choose to rotate the text more (which will narrow each label) or make the chart wider (which will provide more room for the labels). If you don't like either of those options, you can also remove the stagger behavior, but it's necessary to modify the Data Visualization code to do so; I explain how here: http://blogs.msdn.com/b/delay/archive/2010/03/06/turn-your-head-and-check-out-this-post-how-to-easily-rotate-the-axis-labels-of-a-silverlight-wpf-toolkit-chart.aspx#10083036
Hope this helps!