Style definition in Resources/Shared.xaml (updated):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:Double x:Key="fullHeight" >26</system:Double>
<system:Double x:Key="halfHeight" >16</system:Double>
<Thickness x:Key="m">10</Thickness>
<Style TargetType="Button">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="Label">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
</Style>
<Style TargetType="TextBox">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="PasswordBox">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="ListView">
<Setter Property="FontSize" Value="{StaticResource fullHeight}"/>
<Setter Property="Margin" Value="{StaticResource m}"/>
<Setter Property="Padding" Value="10"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="Margin" Value="{StaticResource m}"/>
</Style>
</ResourceDictionary>
Window:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/Shared.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
User control:
<StackPanel Orientation="Horizontal">
<Label Content="Text" Background="AliceBlue"/>
<Label Content="{Binding DecimalValue, FallbackValue=50}" Background="Aquamarine"/>
</StackPanel>
Model:
private decimal _DecimalValue;
public decimal DecimalValue
{
get { return _DecimalValue; }
set
{
if (_DecimalValue != value)
{
_DecimalValue = value;
NotifyOfPropertyChange();
}
}
}
I'm using Caliburn.Micro if it makes any difference.
Result:
Why?
Update: After some Snooping, it turns out that the inner TextBlock of the first Label has margin of 0 and Value Source is Default and for the second it's 10 and Style.
Update 2: After reading up this question it turns out that defined TextBlock style should not be applied to TextBlocks inside Labels. So it seems that existence of binding on a Label somehow changes that.
You must have some other style affecting it.
My best guess would be check your Padding properties, because when I copy and paste your styles to a new project, the heights and margins are the same as your image, however the Padding is different.
Your Labels are actually getting rendered like this:
<Label>
<Border>
<ContentPresenter>
<TextBlock />
</ContentPresenter>
</Border>
</Label>
By messing around with Snoop, I can duplicate your image by altering the Padding of the Border object, so check your XAML to see if you have any implicit styles that change the Padding of your Border tags
Update
After adding the extra styles you've added to your question, I am able to reproduce the results you are getting.
The problem appears to be that the implicit style for your TextBlock is being applied to the TextBlock inside the bound label, but not to the unbound one.
It should be noted this only happens when binding to a decimal value, not to a string.
I suspect this is related to the fact that implicit styles are not meant to cross template boundaries, unless the element inherits from Control. Label inherits from Control, however TextBlock does not.
Since this only happens when binding to a numeric value, my best guess is that the process that determines how to draw a Decimal for Label.Content identifies the parent control as a Label, while the process that writes a string to Label.Content automatically knows to use a TextBlock, and does not apply the implicit styles.
Related
we are using telerik control in our WPF application. I am applying custom style for telerik control but it is not working.
<Style x:Key="RadButtonStyle" TargetType="telerik:RadButton">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="22"/>
<Setter Property="Margin" Value="3,3,5,3"/>
</Style>
<telerik:RadButton Style="{StaticResource RadButtonStyle}"
Content="Login"
Margin="5"
cmd:Click.Command="
{Binding LoginCommand}" />
but style is not getting applied. it is actually hiding the button...
What I did: I have downloaded NugetPackage for Telerik Theme and added reference
<ResourceDictionary Source="/Telerik.Windows.Themes.Office_Black;component/Themes/System.Windows.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Office_Black;component/Themes/Telerik.Windows.Controls.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Office_Black;component/Themes/Telerik.Windows.Controls.Input.xaml"/>
<ResourceDictionary Source="/Telerik.Windows.Themes.Office_Black;component/Themes/Telerik.Windows.Controls.GridView.xaml"/>
Try to base your Style on the implicit one using the BasedOn property:
<Style x:Key="RadButtonStyle" TargetType="telerik:RadButton"
BasedOn="{StaticResource {x:Type telerik:RadButton}}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Width" Value="60"/>
<Setter Property="Height" Value="22"/>
<Setter Property="Margin" Value="3,3,5,3"/>
</Style>
I'm trying to figure out how to change the style of the AvalonEdit CodeCompletion window. However, I can't figure out the right combination of xaml style target/properties to change it. The main thing I'd like to do is get rid of the border, but maybe some additional changes as well.
Here is the xaml I've tried. None of it is affecting the UI.
xmlns:ae="clr-namespace:ICSharpCode.AvalonEdit.CodeCompletion;assembly=ICSharpCode.AvalonEdit"
<Style TargetType="{x:Type ae:CompletionWindow}">
<Setter Property="WindowStyle" Value="None" />
</Style>
<Style TargetType="{x:Type ae:CompletionWindowBase}">
<Setter Property="WindowStyle" Value="None" />
</Style>
<Style TargetType="{x:Type ae:CompletionListBox}">
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type ae:CompletionList}">
<Setter Property="Background" Value="Orange" />
</Style>
Use this style to remove border on window:
<Style TargetType="{x:Type avalonEdit:CompletionWindow}">
<Setter Property="WindowStyle" Value="None"></Setter>
<Setter Property="ResizeMode" Value="NoResize"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
</Style>
To make the styles affect the UI, you can put them in a resource dictionary xaml and parse that with (ResourceDictionary)XamlReader.Parse(ResourcesAsXaml).
Then assign the ResourceDictionary to the Resources property of the CompletionWindow.
I have a style element which has minor edits and mostly repeated. How do i make it more generic - so setter properties are set within based on value versus repeating the code twice
<ResourceDictionary>
<Style x:Key="TextBlockStyleEnvironment" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,4,0,0" />
<Setter Property="FontSize" Value="8" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="TextBlockStyleLocation" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,4,0,0" />
<Setter Property="FontSize" Value="10" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
</ResourceDictionary>
As you see from the code all setter properties are same except Margin and FontSize. Also attached is the screenshot of it on rendering.
Please note - want to keep this self contained within a Style and not have declare at local level in XAML when this being consumed.
Possible values of Env can be Dev,QA,Prod and possible values of location can be TK, LN
Consuming in XAML snippet as follows:
<Grid DataContext="{....}">
<StackPanel>
<TextBlock Text="{Binding Environment}" Style="{StaticResource TextBlockStyleEnvironment}"/>
<TextBlock Text="{Binding Location}" Style="{StaticResource TextBlockStyleLocation}"/>
You can use style inheritance:
<ResourceDictionary>
<Style x:Key="BaseTextBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,4,0,0" />
<Setter Property="FontSize" Value="8" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
<Style x:Key="TextBlockStyleEnvironment" BasedOn="{StaticResource BaseTextBlockStyle}" TargetType="{x:Type TextBlock}" />
<Style x:Key="TextBlockStyleLocation" BasedOn="{StaticResource BaseTextBlockStyle}" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="10" />
</Style>
</ResourceDictionary>
Additionally you can create attached properties and bind to those from within your control templates. This gives you the flexibility of not having to create hundreds of styles just because something minute needs to be different.
A good example of that is a button that has an image. When the mouse is over the image, the image needs to change. Typically you'd have to create a new control template/style for each button that implements that behavior. However, if you create two attached properties - NormalStateImageSource and MosueOverImageSource, you can bind to those in your control template. This allows you to have a single full blown style for the button, and later to declare individual styles for other buttons that only change the values of these attached properties.
There are few techniques in WPF world.
First, if styles are same type, it's possible to use BasedOn attribute:
<Style x:Key="GenericTextBlockStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="5,4,0,0" />
<Setter Property="FontSize" Value="8" />
</Style>
<Style x:Key="TextBlockStyleEnvironment"
BasedOn="{StaticResource GenericTextBlockStyle}"
TargetType="{x:Type TextBlock}">
</Style>
However the BasedOn attribute can get really messy sometimes. It's also possible to do it this way, which will work for elements that are not the same type:
<Thickness x:Key="LeftBorderMargin" Top="10" />
<Style x:Key="TextBlockStyleEnvironment" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="{StaticResource LeftBorderMargin}" />
</Style>
It's common practice to refactor all the colors / margins out from the Style element, for reusability.
One of my Grid currently starts with the following code:
<Grid x:Name="Top_GRID" Margin="4.953,10" Width="817.28">
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="TextBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
</Style>
<Style TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
</Style>
</Grid.Resources>
Just to clarify - I want to declare a Grid in which all TextBlocks are having the Background property set to "Red". All Button margins are set to "3" and so on.
I'd like to move the resource definition to a dictionary file.
Should I somehow wrap it as a Style?
If so, I'm going to have a recursive style declaration which (I think is illegal).
Sounds simple but I can't find the way to do it.
Try this
<Style x:Key="Grid_ControlStyle" TargetType="Grid">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="TextBox">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
</Style>
<Style TargetType="Button">
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="3"/>
</Style>
</Style.Resources>
</Style>
You Need to put all styles for button, TextBox etc. in resourceDictionary file. Then add this file in application resources:
<Application x:Class="Aplication.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources\YourResource.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Then in xaml you will be able to use it like this
<TextBlock Grid.Column="1" Grid.Row="1" Text="bla bla" Style="{DynamicResource YourStyle}"/>
Finally your style should look like
<Style x:Key="StyleName" TargetType="{x:Type TextBlock}">
<Setter Property="Margin" Value="3,3,3,3"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="FontSize" Value="12pt"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
Hope thats what you was looking for.
Please go through the concept of resource dictionary in WPF. Any style, colors, fonts etc whatever is related to look of the application which you wish to be repeated in more than one screen of your application shpuld be placed in the resource dictionary.
x:Key is the property which can be used to access the style anywhere across the application.
For your resource dictionary to be accessible througout the application, place in it app.xaml
Well i have my file Styles.xaml thats merged in the Application.xaml so it applies to every thing..
here are my styles
<Style TargetType="{x:Type Control}" x:Key="baseStyle">
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style TargetType="Button" BasedOn="{StaticResource baseStyle}">
<Setter Property="Margin" Value="2,0,2,0"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="FontSize" Value="50"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="12"/>
</Style>
When im in the editor this seems to work but when i run the application the font-size of the buttons are shrinked to their normal sizes..
My guess is that the buttons create a TextBlock when their content is set to a string and then use the textblock style.. but how can i override this?
You're right about
My guess is that the buttons create a
TextBlock when their content is set to
a string and then use the textblock
style
. See this post.
A workaround is to define a
DataTemplate for System.String, where
we can explicitly use a default
TextBlock to display the content. You
can place that DataTemplate in the
same dictionary you define the
TextBlock style so that this
DataTemplate will be applied to
whatever ContentPresenter effected by
your style.
So adding the DataTemplate at the end to Styles.xaml will fix the problem
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style TargetType="{x:Type Control}" x:Key="baseStyle">
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="FontSize" Value="12"/>
</Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource baseStyle}">
<Setter Property="Margin" Value="2,0,2,0"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Foreground" Value="Red" />
<Setter Property="FontSize" Value="50"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Verdana"/>
<Setter Property="Foreground" Value="Green" />
<Setter Property="FontSize" Value="24"/>
</Style>
<DataTemplate DataType="{x:Type sys:String}">
<TextBlock Text="{Binding}">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}"/>
</TextBlock.Resources>
</TextBlock>
</DataTemplate>
</ResourceDictionary>
This will keep your Style for a TextBlock but the TextBlock created in a Button for example won't be effected by it
I tried your styles, and it works well. So your styles are not the problem. I think it's the place you merged the style as you wrote. You'd better put your ResourceDictionary Styles.xaml in your MainWindow file instead of your Application.xaml.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<TextBlock>TTT</TextBlock>
<Button>BBB</Button>
</StackPanel>
</Window>
But your problem remains unclear, if it's not the solution could you clarify a bit more the way you use your styles by posting this part of your code?