Why window shows style at design time and not at run time - wpf

I created brand new wpf application and on the MainWindow.xaml I have:
why is it that when I run that application I don't see the same font? The xaml code I have is:
<Window.Resources>
<Style TargetType="{x:Type Window}" >
<Setter Property="FontFamily" Value="Arial Black"/>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock>This is a TextBlock</TextBlock>
<Label>This is a Label</Label>
</StackPanel>

this is a known issue, you may need to set explicit style on window.
define the style in application resources or perhaps merge the same using a resource dictionary
eg
<Style x:Key="myWindowStyle" TargetType="{x:Type Window}" >
<Setter Property="FontFamily" Value="Arial Black"/>
</Style>
use the same as
<Window Style="{StaticResource myWindowStyle}" ... />
if you just want to unify the font in the app then perhaps use TextElement.FontFamily
sample
<Window TextElement.FontFamily="Arial Black" ... />
this will help you apply the same font on all the child elements unless explicitly specified.

Related

How to make an exception for Application.Resources style in a specific Grid.Resources

I am doing small WPF app for my own using Visual Studio, C#, .NET Standard and WPF in this specific project.
I have defined style for all TextBlocks and TextBoxes in Applications.Resources like below.
<Application.Resources>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="10"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="10"/>
</Style>
</Application.Resources>
Then in main window I have a grid which contains some buttons.
<Grid>
<Grid.Resources>
<Style TargetType="Button">
<Setter Property="FontSize" Value="50" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="50"/>
</Style>
</Grid.Resources>
<Button Grid.Column="0" Content="DASHBOARD" Command="local:CustomCommands.ShowDashboard"/>
</Grid>
I would like to set for the textblocks/textboxes in this specific buttons a wider font.
I tried for many different syntax but could not manage it. I tried also do define x:Key for this style in Grid.Resources and use it in this specific Button control. This wasn't work either.
Can anyone let me know which way should I let know my application that text in this buttons would have bigger font size?
The TextBlock created for string contents by the ContentPresenter inside the Button template doesn't apply the locally-defined resources, i.e. those in your Grid.
The easiest way to solve your problem would be to explicitly define a TextBlock as the Button's content.
<Grid>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="50"/>
</Style>
</Grid.Resources>
<Button Grid.Column="0" Command="local:CustomCommands.ShowDashboard">
<TextBlock Text="DASHBOARD" />
</Button>
</Grid>

Possible to create an implicit style that is used, by default, as the base for other styles?

I'm trying to figure out a way to create an implicit style for a custom control, that will be inherited by other styles applied to the control.
For example, let's say I have a control FancyButton. Then I can define an implicit style by putting this in my app resources:
<Style TargetType="my:FancyButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="my:FancyButton">
<TextBlock Text="hello world" Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then users of the control will see "hello world" in green just by writing:
<my:FancyButton Foreground="Green" />
The problem is, if someone wants to define a green-colored style like this ...
<Style TargetType="my:FancyButton" x:Key="GreenButton">
<Setter Property="Foreground" Value="Green" />
</Style>
<my:FancyButton Style="{StaticResource GreenButton}" />
... then they will have lost the implicit style's control template, and will not see the "hello world".
Of course, you can define a base style, which the implicit style inherits ...
<Style TargetType="my:FancyButton" x:Key="FancyButtonDefaultStyle">
<!-- ... -->
</Style>
<Style TargetType="my:FancyButton" BasedOn="{StaticResource FancyButtonDefaultStyle}">
</Style>
... and that way users of the control can inherit the default style:
<Style TargetType="my:FancyButton" x:Key="GreenButton" BasedOn="{StaticResource FancyButtonDefaultStyle}">
<Setter Property="Foreground" Value="Green" />
</Style>
But it seems awkward to force users of the control to remember to inherit a default style based on a key. Isn't there some way to make a custom control's styles inherit the implicit style, in the same way that the framework controls do?
Ie, I want my FancyButton to behave in the same way a Button does, where I can define a style that doesn't wipe out the other default style properties (esp. ControlTemplate):
<Style TargetType="Button" x:Key="GreenButton">
<Setter Property="Foreground" Value="Green" />
</Style>
You need to put the implicit style definition
<Style TargetType="my:FancyButton">
<!-- etc -->
</Style>
in the special "Themes/Generic.xaml" resource dictionary (in the same assembly as where the control class is defined). This makes all styles inherit from the implicit style, as you wanted.
Sorry for quoting. :)
Hope this helps.
Here's my code:
MainPage.xaml:
<UserControl x:Class="SilverlightApplication4.MainPage"
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"
xmlns:local="clr-namespace:SilverlightApplication4"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="local:TemplatedControl1"
x:Key="myCustomTemplate">
<Setter Property="Foreground"
Value="Purple" />
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot"
Background="Yellow"
Width="500"
Height="500">
<local:TemplatedControl1 Style="{StaticResource myCustomTemplate}" />
</Grid>
</UserControl>
Now in TemplatedControl.cs don't forget to put this:
this.DefaultStyleKey = typeof(TemplatedControl1);
And finally put your implicit style definition in Themes\Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SilverlightApplication4">
<Style TargetType="local:TemplatedControl1">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TemplatedControl1">
<TextBlock Text="hello world"
Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
With this method, the result should be purple text in a terrible yellow background. :)
Thanks to #Tanis83 for pointing out the (very simple) answer. I just needed to put the implicit style ...
<Style TargetType="my:FancyButton">
<!-- etc -->
</Style>
in the special "Themes/Generic.xaml" resource dictionary (in the same assembly as where the control class is defined). This makes all styles inherit from the implicit style, as I wanted.

How to extend instead of overriding WPF Styles

I want to use custom theme in my application and as far as I know I can accomplish this by using resource dictionary and referencing it in App.xaml. Styles would override the defaults like this:
<Style TargetType="{x:Type Label">
<Setter Property="Foreground" Value="Green" />
</Style>
Now as I guess the default Label style is overriden with same values but all my label fonts are green. The problem starts when I want to style one label somewhere again. When I want to change some other property in my Grid like this
<Grid.Resources>
<Style TargetType="{x:Type Label">
<Setter Property="FontSize" Value="28" />
</Style>
</Grid.Resources>
All labels inside my grid are losing their foreground color and have default one again (didn't I override defaults in previous step?). After some tries I found out that to do this properly i have to add another property to Style declaration BasedOn={StaticResource {x:Type Label}}" and it works. This is kind of weird for me because now I will have to repeat same BasedOn code in whole app and this is not how styling works - this should be done automatically! For example in HTML + CSS styles are inherited and merged and in WPF they are replaced...
Notice that when I don't use any styles controls still get their look from somehwere (System Themes?). How can I tell them to look for defaults somewhere else so without any additional code on styles they will think that they should be green by default?
Is there any way I can automate setting BasedOn property? Or maybe there is a better to do this overally?
I had the same problem. I used Zack's answer and improved it like following so if you don't specify a style the overridden default is still taken in account. It's basically what you would have done but just once in the ResourceDictionary.
<Window x:Class="TestWpf.RandomStuffWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Stuff Window">
<Window.Resources>
<ResourceDictionary>
<!-- Default Label style definition -->
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="Green" />
</Style>
<!-- Extending default style -->
<Style TargetType="{x:Type Label}"
x:Key="LargeGreenForegroundLabel"
BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="FontSize" Value="28" />
</Style>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<Label Content="GreenForegroundLabel" /> <!-- Uses default style -->
<Label Style="{StaticResource LargeGreenForegroundLabel}"
Content="LargeGreenForegroundLabel" />
</StackPanel>
</Window>
Wpf has different levels of styles, that are applied in order of global > local. A style set directly on a control will override a style set globally, like in your example. I was trying to find a list of all the different places that a control looks for its styles but I cannot find one at the moment. As far as I know, you will have to use the BasedOn property to inherit a style and not completely override the properties of that style with the style you set locally.
Here is an example of a resource dictionary that has styles based on another style, so that you don't have do repeat the BasedOn binding over and over, you can just set the style on the specific element you want to have that style.
<Window x:Class="TestWpf.RandomStuffWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Random Stuff Window">
<Window.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type Label}"
x:Key="GreenForegroundLabel">
<Setter Property="Foreground" Value="Green" />
</Style>
<Style TargetType="{x:Type Label}"
x:Key="LargeGreenForegroundLabel"
BasedOn="{StaticResource GreenForegroundLabel}">
<Setter Property="FontSize" Value="28" />
</Style>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<Button Click="Button_Click">Click</Button>
<Label Style="{StaticResource GreenForegroundLabel}"
Content="GreenForegroundLabel" />
<Label Style="{StaticResource LargeGreenForegroundLabel}"
Content="LargeGreenForegroundLabel" />
</StackPanel>
</Window>

How to set a default Margin for all the controls on all my WPF windows?

I want to set a default Margin of 3 on all the controls I put on all my windows and be able to override this value just on a really few number of items.
I've seen some approaches like doing styles but then I need to style everything, I would prefer something than can be done for all the controls together. I've seen other things like the MarginSetter but looks like it does not traverse subpanels. I want the Margin only on the controls I put at the window, nothing to do with the borders or other things of the visual tree.
Looks something pretty basic to me. Any ideas?
Thanks in advance.
The only solution I can find is to apply the style to each of the controls you are using on the window (I know that's not quite what you want). If you're only using a few different control types it's not too onerous to do something like this:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- One style for each *type* of control on the window -->
<Style TargetType="TextBox">
<Setter Property="Margin" Value="10"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<StackPanel>
<TextBox Text="TextBox"/>
<TextBlock Text="TextBlock"/>
</StackPanel>
</Window>
Good luck...
You can link all of your Margin properties by referring to a "Thickness" defined in your resources. I just did this in a project...
<!-- somwhere in a resource-->
<Thickness x:Key="CommonMargin" Left="0" Right="14" Top="6" Bottom="0" />
<!-- Inside of a Style -->
<Style TargetType="{x:Type Control}" x:Key="MyStyle">
<Setter Property="Margin" Value="{StaticResource CommonMargin}" />
</Style>
<!-- Then call the style in a control -->
<Button Style="{StaticResource MyStyle}" />
<!-- Or directly on a Control -->
<Button Margin="{StaticResource CommonMargin}" />
The key for me was figuring out that Margin was defined by "Thickness". Let me know if that's clear enough or if you need me to put it in a fully working XAML example.
You can apply margin in your buttons style. And when you use buttons with this style in StackPanel wpf will apply need spacing.
for example
define in resourcedictionary or whatever:
<Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Margin" Value="10"/>
....
</Style>
then in yor StackPanel xaml definition:
<StackPanel>
<Border BorderThickness="0"/>
<Button x:Name="VertBut1" Style="{StaticResource myButtonStyle}" Content="Button1"/>
<Button x:Name="VertBut2" Style="{StaticResource myButtonStyle}" Content="Button2"/>
<Button x:Name="VertBut3" Style="{StaticResource myButtonStyle}" Content="Button3"/>
</StackPanel>
regards
Georgi

Setting an Elements.Resource Style using BasedOn within a Resource Dictionary

I have a Resource Dictionary that I am using to define the look-and-feel (style) for my application.
I have just created another Resource Dictionary that contains DataTemplates that I am using on several different screens (and even multiple times within the same screen) to display my business objects.
I would like to change some of the default styles within my DataTemplates so that the controls fit better; however I would like the controls to inherit the same style as the rest of the screen. So, naturally I want to use the BasedOn property for this task.
The problem that I am having is that I'm not sure what to set the BasedOn property to.
For example, in the resource dictionary that contains my styles (called "myStyle.xaml") I have:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="#F5F5F5" />
<Setter Property="FontSize" Value="12"></Setter>
<Setter Property="Width" Value="120"></Setter>
<Setter Property="FontFamily" Value="Arial"></Setter>
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="FontSize" Value="12"></Setter>
<Setter Property="Width" Value="120"></Setter>
<Setter Property="Height" Value="25"></Setter>
<Setter Property="Background" Value="Black"></Setter>
</Style>
<!-- .... and so on .... -->
</ResourceDictionary>
I am using this resource in the following window:
<Window x:Class="SiteSetupWindow4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:primatives="clr-namespace:System.Windows.Controls.Primitives;assembly=PresentationFramework"
Title="A Screen">
<Window.Resources>
<ResourceDictionary x:Key="defaultStyleX">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary x:Name="DefaultStyles" Source="Resources/myStyle.xaml" />
<ResourceDictionary x:Name="Templates" Source="Resources/myTemplates.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Now, I have another Resource Dictionary that contains DataTemplates that I am using within my window. It is called "myTemplates". The style is applied to the DataTemplate as expected; however, I would like to overwrite some aspects of the style within the DataTemplate (Like width for example).
This is what I have tired, however I cannot get the BasedOn property to work...
(myTemplate.xaml)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="PanelInfo">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Width" Value="120" />
</Style>
<Style TargetType="Label">
<Setter Property="Width" Value="180" />
</Style>
<Style TargetType="ComboBox">
<Setter Property="Width" Value="120" />
</Style>
<StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<Label Content="Type:"></Label>
<ComboBox>
<ComboBoxItem Content="{Binding Path=Type}" IsSelected="True"></ComboBoxItem>
</ComboBox>
<!--...and so on -->
</StackPanel>
</StackPanel>
</ResourceDictionary>
This fails....I have also tried using DynamicResource, but this also fails.
I'm not sure how to get around this.
Any advise would be greatly appreciated!
Thanks,
-Frinny
I was having the same problem with an extended Button Style.
The ResourceKey= is what solved it for me.
This worked:
<Style x:Name="ButtonVisibility"
TargetType="{x:Type Button}"
BasedOn="{StaticResource ResourceKey={x:Type Button}}">
The way you have BasedOn for a type is correct. This will work in theory as long as, at run time, the style that you are basing it on is merged into the tree correctly. Make sure you have the "myStyles.xaml" merged in correctly. You can check this by removing your style you tried to modify and make sure it displays correctly from your style in "myStyles.xaml."
If it isn't there are a lot of places you can go wrong, but it always helps to try merging the styles in the file you are working on, then work up the tree to see where it's missing.
This utility will help you look at what is happing in the tree at run time.
http://blois.us/Snoop/

Resources