How can I stop ToolTips from inheriting my TextBlock style? - c#

I've defined a style within my application resources that I want all of my textblocks to inerit :
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="1" ShadowDepth="0" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontWeight" Value="Bold" />
</Style>
I don't want to have to go through and explicitly dictate the style on each textblock - I just want all of them to inherit this style naturally.
Unfortunately, when I define a tooltip, that tooltip also picks up this style. I'm guessing it's because the thing incorporates a TextBlock somewhere in it's design.
What I AM okay with is having to go through and style each defined tooltip ( since they are used less ubiquitously throughout my application ), so if there's some way to define a tooltip style that will override the inherited textblock style, I'm fine with that.
So, what can I do to stop my tooltips from inheriting the TextBlock style?

It's a terrible idea to set a global implicit style on TextBlock, and this is why. TextBlock is the primitive that displays text. It's much better to set the implicit TextBlock style only where it's needed, not universally.
Or consider using Label instead of TextBlock for the styled text instances, and have an implicit Label style. That's one reason why Label exists. You can style the padding/margin etc. to make it look exactly the way you want.
But if you want the quick and dirty and easy way to work around a bad decision, you can use the implicit-style-localized-within-a-style trick that grandpa used to flummox General Rommel at El Alamein:
<Style TargetType="ToolTip">
<Style.Resources>
<!-- Implicit style for TextBlocks within ToolTips -->
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Effect" Value="{x:Null}" />
</Style>
</Style.Resources>
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Regular" />
<Setter Property="Effect" Value="{x:Null}" />
</Style>

Related

WPF - Change Scrollbar's margin of a TextBox using Styles

I have a defined an implicit style for Scrollbar and set some properties and I use it for most ScrollViewrs. Part of the Style is :
<Style x:Key="{x:Type ScrollBar}" TargetType="{x:Type ScrollBar}">
<Setter Property="Background" Value="#FF283542" />
<Setter Property="Margin" Value="0,-32,0,0" />
<Setter Property="Width" Value="5" />
</Style>
But I have some TextBoxes which I want them to have the same implicit Scrollbar style for their Scrollbars but with a diffrent margin.
I can do it by adding Resources to every TextBox and override the implicit ScrollBar style like :
<TextBox Style="{StaticResource big-text-style}">
<TextBox.Resources>
<Style TargetType="{x:Type ScrollBar}"
BasedOn="{StaticResource {x:Type ScrollBar}}">
<Setter Property="Margin" Value="0"/>
</Style>
</TextBox.Resources>
</TextBox>
This code gives me the functionality I want. But the problem with this approach is that I have to write these lines of code of every TextBox! It would be much better if I could put this as part of the TextBox style itself.
I wonder is there a way to put it in the TextBox's Style so that every TextBox which has big-text-style(for example), have the overriden ScrollBar ?
Or is there a better way to implement this kind of thing ?
Thank you for the help!
You can add the overriding ScrollBar style to the Resources of the TextBox style itself:
<Style x:Key="big-text-style" TargetType="TextBox">
<Style.Resources>
<Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource {x:Type ScrollBar}}">
<Setter Property="Margin" Value="0"/>
</Style>
</Style.Resources>
</Style>

while Inherit style in WPF it affect parent style

In WPF i have a style for the control like below,
<Style TargetType="local:CustomControl">
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Gray" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
<Setter Property="Padding" Value="3,0,3,0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>
Now i need to override customcontrol border for some other place like below,
<Style TargetType="local:CustomControl" BasedOn="{StaticResource {x:Type local:CustomControl}}">
<Setter Property="BorderThickness" Value="1" />
</Style>
My problem is when i am using above code it override the 1st written code. is my code is correct.
Note: the base style is only written with target type. i need to override that control border in some other place without affect base code.
is it possible ? please help me to resolve this problem.
thanks in advance.
If you declare a Style without an x:Key, it will override the default style for that control.
<Style TargetType="local:CustomControl">
So the code above will effect all CustomControl elements throughout the entire application (or within the scope).
If you do not want to override the base style, you can give your Style an x:Key, like so:
<Style TargetType="local:CustomControl" x:Key="MyAwesomeStyle">
When you create your control, you will then have to reference the Style. Here's an example:
<local:CustomControl Style="{DynamicResource MyAwesomeStyle}" ... />
Accidentally I saw some example which can be useful in solving the mentioned problem. In your example own custom control has been used, in my example - a button.
<Grid>
<Button Style="{StaticResource AddButtonStyle}" Tag="Add" Click="addClick" />
</Grid>
Code for AddButtonStyle:
<Style x:Key="AddButtonStyle" TargetType="Button" BasedOn="{StaticResource AppBarButtonStyle}">
<Setter Property="Content" Value="✅"/>
</Style>
AddButtonStyle based on AppBarButtonStyle. Below code for it.
<Style x:Key="AppBarButtonStyle" TargetType="Button">
<Setter Property="MinWidth" Value="40" />
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="88" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Segoe UI Symbol" />
<Setter Property="FontSize" Value="18" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">. . .
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
On this example base, you must declare a Style with an x:Key, and should not set any value to Content (in you example BorderThickness) property in the inherited style.

Design responding Triggers, defining and using WPF

Recently I read about styles and control templates. As it says control templates are responsible for whole control design. But, I want for example to change only SPECIFIC part of the default control template, for example when mouse is over, or control has focus, when I wrote this:
<Style x:Key="StyleTextBox" TargetType="TextBox">
<Setter Property="Margin" Value="5, 0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="SelectionBrush" Value="#CCFBE6D9"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
..whole template got overridden... and its kinda not cool...
So how to change only isMouseOver visual style, without overriding the whole default style?
The whole template got replaced because your XAML says, "set the Template to this ControlTemplate that I'm declaring right here." Problem is, your template is empty. Use a template when you want to tell WPF, "represent the control using this visual tree". You gave it an empty visual tree and got exactly what you asked for ;).
In this case, however, your intention isn't to change the visual structure of the control; you just want to change a property. You can still use a Trigger and Setter for this, but you need not create a template to do so. A Style has its own collection of triggers, so you can just move it there:
<Style x:Key="StyleTextBox" TargetType="TextBox">
<Setter Property="Margin" Value="5, 0"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="SelectionBrush" Value="#CCFBE6D9"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="Black" />
</Trigger>
</Style.Triggers>
</Style>
This works because you're just changing a property of the styled control; generally, you can expect templates to honor the top-level properties of the controls to which the template is applied. For example, the default TextBox template should ensure that the TextBox is drawn with a background conforming to the templated parent's Background property.
Triggers on templates are more useful in cases where you want to manipulate a specific sub-element declared within a custom template.

Watermark fontsize/family

I am currently creating a TextBox with a watermark text and have a little styling problem.
To create the Watermark itself I have included the code explained in here
Watermark / hint text / placeholder TextBox in WPF
I did not use the accepted answer, but the one with the highest votes. (the one using Adorner)
My textblock looks like this:
<AdornerDecorator>
<TextBox HorizontalAlignment="Right"
VerticalAlignment="Center"
Width="190"
Padding="16,2,20,2">
<utils:WatermarkService.Watermark>
<TextBlock Text="Search" />
</utils:WatermarkService.Watermark>
</TextBox>
</AdornerDecorator>
Now I face the problem that with this attached property, the textblock in it gets out of scope from my styling I have declared in app.xaml.
The styling looks like this:
<Style TargetType="{x:Type Window}">
<Setter Property="FontFamily"
Value="Tahoma" />
<Setter Property="FontSize"
Value="8pt"></Setter>
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}" />
</Style>
How is it possible to style the textblock within the attached property in app.xaml, preferable with basedon this style so I dont have to declare it serval times.
Declare same style for TextBlock as well in Application resources. This way it will be applied to all TextBlocks in your application no matter whether they are part of Adorners or window.
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily"
Value="Tahoma" />
<Setter Property="FontSize"
Value="8pt"></Setter>
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
</Style>
UPDATE
If you don't want to duplicate resources, best you can get is use Label instead of TextBlock. That way you can have style applied on Control and can derive styles for Window and Label from that.
But this won't work for TextBlock since it doesn't derive from Control.
<Style TargetType="Control" x:Key="BaseStyle">
<Setter Property="FontFamily" Value="Tahoma" />
<Setter Property="FontSize" Value="8pt"></Setter>
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"/>
</Style>
<Style TargetType="{x:Type Window}"
BasedOn="{StaticResource BaseStyle}"/>
<Style TargetType="{x:Type Label}"
BasedOn="{StaticResource BaseStyle}"/>
Then if you use Label inside AdornerDecorator in place of TextBlock, it will work fine.

Setting foreground for whole Windows Phone's application

How to change foreground color for all controls in the application? I need to change color for: textboxes, textblocks, borders of buttons.
It will take too long to do it one by one (over 100 controls).
This is what styles are for. You can add styles in your app.xaml file. Something like:
<Application.Resources>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Foreground" Value="White" />
</Style>
</Application.Resources>
Assuming you are programming for Windows Phone 7.1 (Mango) or later, you can use a Style in your App.xaml file, add the following code inside your Application.Resources tag and customize as needed. The styles will be applied to all Pages in your application (you can still override individual properties directly in the corresponding element tags).
<Application.Resources>
<Style TargetType="Button">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="FontSize" Value="20"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="Blue" />
</Style>
</Application.Resources>

Categories

Resources