Add border into my TextBlock Style - wpf

I have this style:
<Style x:Key="labelStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="Gray" />
</Style>
I am using this style over my chart SmartLabel and i want to add border.
Any suggestions ?

you can override template of textblock .put one border in its template and a textblock for borders child.

wrap the Textblock inside a Border:
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock ... />
</Border>
You can use other properties on the border too, like BorderBrush, Thikness and so on

Related

WPF toolbar's style not working

I'm using a resource dictionary in my wpf proyect.
The dictionary has these 2 styles:
<Style x:Key="MyMenu" TargetType="Menu">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style x:Key="MyToolbar" TargetType="ToolBar">
<Setter Property="Background" Value="Black"/>
</Style>
And in my XAML file, I use these 2 styles as it follows:
For the menu:
<Menu Name="menuMainBar" Style="{DynamicResource MyMenu}" IsMainMenu="True" VerticalAlignment="Top" Margin="0,10,0,0">
<MenuItem ...
</Menu>
For the toolbar:
<ToolBarTray Name="toolBarTrayRigth_wargames" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50">
<ToolBar Name="toolBarRigth_wargames" Style="{StaticResource MyToolbar}" BorderThickness="0,0,1,0">
<Button ...
</ToolBar>
</ToolBarTray>
This is the result:
As you can notice, the menu takes the style correctly, but the toolbar isn't affected by the style at all.
I tried removing all the style elements from the toolbartray tag, as it follows:
<ToolBarTray Name="toolBarTrayRigth_wargames">
...
</ToolBarTray>
And now the toolbar works, but as you can see, now the toolbarTray is not how I want it to be (I want a vertical toolbar, not a horizontal toolbar):
I also tried setting the background of the ToolBar directly in the xaml file:
<ToolBarTray Name="toolBarTrayRigth_wargames" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top" Width="50">
<ToolBar Name="toolBarRigth_wargames" BorderThickness="0,0,1,0" Background="Black">
<Button ...
</ToolBar>
</ToolBarTray>
...and it works:
But I don't want to do that, I want to use a resource dictionary for my toolbar's style.
any ideas on how to achieve that?
I found, bizarrely, that if I set the Orientation of the parent ToolBarTray to Horizontal, that your ToolBar style was able to set the background on the ToolBar.
I also found that with the ToolBarTray orientation still being Vertical, this worked to set the ToolBar's background:
<Style x:Key="MyToolbar" TargetType="ToolBar">
<Style.Triggers>
<!--
This is intentional. A conventional setter was found not to set the background
when the parent ToolBarTray's Orientation was Vertical.
-->
<DataTrigger Binding="{Binding Source={x:Null}}" Value="{x:Null}">
<Setter Property="Background" Value="Black" />
</DataTrigger>
</Style.Triggers>
</Style>
I find this very strange.
as #EdPlunkett found, its a strange Setter in the default template in the Trigger for Vertical Orientation:
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="Margin" TargetName="Grid" Value="1,3,1,1"/>
<Setter Property="Style" TargetName="OverflowButton">
<Setter.Value>
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="#FFEEF5FD"/>
you can edit the template (in Document Outline panel, right click on the ToolBar element > Edit Template > Edit a Copy...), and remove this Setter.

Override property of custom style

I have Style that applies to all of the buttons of my application:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
... some Triggers here
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I change properties (e.g. FontWeight, FontSize etc.) in XAML? I tried this:
<Button FontWeight="Bold" FontSize="30" Foreground="Red">
</Button>
In the designer-view, I see the changes. But during runtime those changes are not applied.
After some investigation, I also have a Style for all TextBlock like this:
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="16" />
<Setter Property="FontFamily" Value="Segoe UI Semibold" />
<Setter Property="Foreground" Value="White" />
</Style>
This Style seems to override the TextBlock that is used on the Button. I still can't change the Text Properties in XAML.
Here's what it looks like if I use the Styles above in an empty project:
In the designer, the changes are applied, during runtime the one from the TextBlock are applied. If I assign a x:Key to the TextBlock, it works fine. But then I have to assign this Style to every TextBlock used in the app manually.
You are facing typical style inheritance issue in wpf.
A control looks for its style at the point when it is being initalized. The way the controls look for their style is by moving upwards in logical tree and asking the logical parent if there is appropriate style for them stored in parent's resources dictionary.
In your case, you are using ContentPresenter in button as a default behaviour. and it is using TextBlock to represent text in button by default.
Therefore at the time of initialization, ContentPresenter finding TextBlock style and applying to represent content in button.
If you want to restrict ContentPresenter to look for the style then you have to bind a blank style to content presenter so that it will not look for any further style.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Ellipse x:Name="StatusButtonCircle" Stroke="Black" StrokeThickness="0" Fill="AliceBlue" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircle" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<Ellipse x:Name="StatusButtonCircleHighlight" Margin="4" Stroke="Black" StrokeThickness="2" Stretch="Uniform">
<Ellipse.Width>
<Binding ElementName="StatusButtonCircleHighlight" Path="ActualHeight"/>
</Ellipse.Width>
</Ellipse>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter.Resources>
<Style TargetType="TextBlock" BasedOn="{x:Null}"/>
<!-- Assigned Blank style here therefore it will not search for any further style-->
</ContentPresenter.Resources>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You can do it with the BasedOn. I show you an example.
<Window.Resources>
<Style TargetType="ToggleButton" BasedOn="{StaticResource DefToggleButton}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Content" Value="Some Cool Stuff"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Content" Value="More Stuff"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
Here in my resources I have DefToggleButton, now in my xaml file I can set up any Property according to my need (which in this case is the FontWeight and Content Property).
I think if you remove the Template from your Style, then you can do what you want to do, like this:
<Window.Resources>
<Style TargetType="Button" x:Key="stBtn>
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Segoe UI Semibold" />
</Style>
</Window.Resources>
The Template that you have says, that all Buttons should be shown as a Border with a ContentPresenter inside, which is not what you have asked.
Without the Template, you can define your Buttons like this:
<Button Content="Hi!" Style="{StaticResource stBtn}" Foreground="Red" >
Like this, you have a Blue Button with Red Foreground.
=================
Edit
So what if you define a Template, and use it in you style, like this?
Then, by TemplateBinding you can define that the Foreground and teh Content come later, when the Button is actually defined.
<Window.Resources>
<ControlTemplate x:Key="ctBtn" TargetType="{x:Type Button}">
<Label Background="Green" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}"/>
</ControlTemplate>
<Style x:Key="stBtn2" TargetType="{x:Type Button}">
<Setter Property="Template"
Value="{StaticResource ctBtn}" />
</Style>
<Window.Resources>
Then by defining the Button:
<Button Content="Hi!" Style="{StaticResource stBtn2}" Foreground="Red" >
===============
Edit2
So the general idea is that you can define a TemplateBinding for the properties of the elements in your template. So for example,you have an Ellipse in your template:
<Ellipse Fill="{TemplateBinding BorderBrush}" />
This defines that the Fill property of your Ellipse comes from the BorderBrush of your Button (Assuming that the template is targeting a Button)
Accordingly, you can put a Label in your Template, and set a TemplateBinding for its Forground and FontWeight property.
<Label Foreground="{TemplateBinding Foreground}" />
First, for this issue to be reproduced, Styles need to be set within a ResourceDictionary which is then added to Application.Resources (precisellyTextBlock global style). Setting Styles within for example Window.Resources will not reproduce the issue.
Global TextBlock Style is applied to the TextBlock created by ConentPresenter
As noticed in the question, the issue is that the global (keyless) Style for TextBlock is applied to the TextBlock created by ContentPresenter when it concludes the content to display is a string. For some reason this doesn't happen when that Style is defined within Window.Resources. As it turns out, there is more to this than just "controls are looking for their styles within their parent's resources".
ControlTemplate is a boundary for elements not deriving from Control class
For TextBlock (which doesn't derive from Control class, but from UIElement) within ControlTemplate, it means that wpf will not look for it's implicit Style beyond it's templated parent. So it won't look for implicit Style within it's parent's resources, it will apply application level implicit Style found within Application.Resources.
This is by design (hardcoded into FrameworkElement if you will), and the reason is exactly to prevent issues like this one. Let's say you're creating a specific Button design (as you are) and you want all buttons in your application to use that design, even buttons within other ControlTemplates. Well, they can, as Button does derive from Control. On the other hand, you don't want all controls that use TextBlock to render text, to apply the implicit TextBlock Style. You will hit the same issue with ComboBox, Label... as they all use TextBlock, not just Button.
So the conclusion is: do not define global Style for elements which don't derive from Control class within Application.Resources, unless you are 100% sure that is what you want (move it to Window.Resources for example). Or, to quote a comment I found in source code for MahApps.Metro UI library: "never ever make a default Style for TextBlock in App.xaml!!!". You could use some solution to style the TextBlock within your Button's ControlTemplate, but then you'll have to do it for Label, ComboBox, etc... So, just don't.

Create link lable style WPF

I created the following style:
<Style x:Key="LinkText" TargetType="{x:Type Label}">
<Setter Property="Label.FontFamily" Value="Verdana"/>
<Setter Property="Label.FontSize" Value="13"/>
<Setter Property="Label.Foreground" Value="Blue"/>
<Setter Property="TextBlock.TextDecorations" Value="Underline"/>
</Style>
But when I try to use it on some label the UnderLine is missing.
I wrote at my UserControl the next Label:
<Label Grid.Column="1" HorizontalAlignment="Right" Style="{StaticResource LinkText}">
<TextBlock>some text</TextBlock></Label>
I see all the style properties except the underLine propery
How can I create Label style with underline?
Try to use a TextBlock control instead of a Label control. It behaves more or less exactly the same and should allow you to underline the text.
The TextBlock.TextDecorations dependency property belongs to the TextBlock control so you must use it to underline text.

How do I specify common layout markup or rules for controls in XAML?

I'm a WCF newbie, and I wonder, is it possible to declare in XAML that all my TextBoxes should have a height of 26, for example? That is, not to set the height of each item individually?
You need to define a style for your textbox
This will style the textbox when required
<Style x:Key="myTextBoxStyle">
<Setter Property="Height" Value="26" />
</Style>
<TextBox Text="Hi" Style="{StaticResource myTextBoxStyle}"/>
This will style all the textboxes
<Style TargetType="{x:Type TextBox}">
<Setter Property="Height" Value="26" />
</Style>
Put your Style into your resources block

Remove focus rectangle from ListBox item

How do you remove the focus rectangle from a silverlight ListBox? I have this code:
<ListBox x:Name="MyListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
...snipped...
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
and when i run it i get the exception
System.Windows.Markup.XamlParseException: Invalid attribute value FocusVisualStyle for property Property. [Line: 47 Position: 38]
what am i doing wrong? Many thanks :)
In Silverlight the ListBoxItem type doesn't have a FocusVisualStyle property hence the error.
In order to acheive your goal you need to supply a new template for the ListBoxItem. Form the Silverlight documentation you'll find the default template in ListBox Styles and Templates.
Copy the ListBoxItem template into a Static resource (the App.Xaml would be a good place)
<ControlTemplate TargetType="ListBoxItem" x:Key="ListBoxItemSansFocus">
<!-- copy of the rest of the control template here -->
</ControlTemplate>
Now remove the StoryBoard from the "Focused" VisualState and remove the final rectangle that has the name "FocusVisualElement".
Now in make your ContainerStyle property look like:-
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template" Value="{StaticResource ListBoxItemSansFocus}" />
</Style>
</ListBox.ItemContainerStyle>

Resources