How to set Foreground of a TextBlock in a nested grid? - wpf

I've a TextBlock inside a Grid which is inside a PopupBox provided by MaterialDesignInXaml, a sample structure:
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
<materialDesign:PopupBox>
<Grid>
<TextBlock Text="Foo" />
</Grid>
</materialDesign:PopupBox>
I'm trying to apply the TextBlock foreground as a global resource in my App.xaml:
<Style TargetType="materialDesign:PopupBox">
<Setter Property="TextBlock.Foreground" Value="red" />
</Style>
but not seems to be working, any help?

You will need to define an implicit Style for the Grid. Try this:
<Style TargetType="materialDesign:PopupBox">
<Style.Resources>
<Style TargetType="Grid">
<Setter Property="TextElement.Foreground" Value="Red" />
</Style>
</Style.Resources>
</Style>

Related

Wpf - Create a Style in a resource dictionary that sets properties of children of a grid [duplicate]

Is it possible to define a ResourceDictionary in a Style?
For example, suppose I wanted to have two different Styles for StackPanels and in one I want all the buttons to be blue and the other I want them to be red. Is this possible?
Something like
<Style x:Key="RedButtonsPanel" TargetType="{x:Type StackPanel}">
<Setter Property="Orientation" Value="Horizontal" />
<Setter Property="StackPanel.Resources">
<Setter.Value>
<ResourceDictionary>
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
The above code fails with an error about the Property value of a Setter cannot be null (even though it's obviously not null).
I can do something like
<ResourceDictionary x:Key="RedButtons">
<Style TargetType="{x:Type Button}">
<Setter Property="Width" Value="100" />
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
<StackPanel Resources={StaticResource RedButtons} />
However I was wondering if there was a way to merge the ResourceDictionary into the style.
Try adding the Style(s) for each TargetType to the DockPanel Style.Resources.
I did something similar with a DockPanel Style. Wanted all Buttons or Separators added to the DockPanel to get styled in a consistent manner.
Here's a sample:
<Style x:Key="DockPanelToolBarStyle" TargetType="{x:Type DockPanel}">
<Style.Resources>
<Style TargetType="Button" BasedOn="{StaticResource ButtonToolBarStyle}" />
<Style TargetType="Separator" BasedOn="{StaticResource SeparatorToolBarStyle}" />
</Style.Resources>
<Setter Property="Height" Value="45"/>
<Setter Property="Background" Value="{StaticResource ToolBarBrush}"/>
</Style>
StackPanel.Resources is not a DependencyProperty and therefore I don't believe you will be able to set that property within the style.

How to set a control resource dictionary in a Style in XAML?

I have a UI in Silverlight with some borders, and with a TextBlock inside that borders. There will be other TextBlocks outside borders.
<Border>
<TextBlock>This text should be centered</TextBlock>
</Border>
<Border>
<TextBlock>This one too</TextBlock>
</Border>
<TextBlock>this one shouldn't</TextBlock>
What I'm trying to achieve is to format all TextBlock's inside a Border, without having to set the style in every TextBlock. If it was CSS , it will be something like that : .border .textBlock { (...) }
I know i can set a style inside the scope of a border:
<Border>
<Border.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource DefaultTextBlockStyle}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
</Style>
</Border.Resources>
<TextBlock>Centered Text</TextBlock>
</Border>
But I would still need to set this to every border in my page. So now i presente the question, can i set in a style, in order to set it one time to affect all Borders? I tried the code bellow, but it didn't work. It didn't give me any errors, but it didn't affect the TextBlock formatting either.
<Style TargetType="Border">
<Setter Property="Resources">
<Setter.Value>
<ResourceDictionary>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</ResourceDictionary>
</Setter.Value>
</Setter>
</Style>
Try this:
<Style TargetType="Border">
<Style.Resources>
<Style TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
</Style.Resources>
</Style>
This works in WPF. In Silverlight I am afraid you cannot do this though.

Customize WPF Toolkit autocompletebox

WPF Toolkit library has Autocompletebox control.
1. How to place an icon at the left of its Textbox part?
2. How to add shadow to the borders of the suggestions popup?
Changing TextBoxStyle property does not give any results.
<!-- xmlns:extendedControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" -->
<extendedControls:AutoCompleteBox>
<extendedControls:AutoCompleteBox.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="Padding" Value="20,0,0,0" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/img.png" Stretch="None" AlignmentX="Left" />
</Setter.Value>
</Setter>
</Style>
</extendedControls:AutoCompleteBox.TextBoxStyle>
</extendedControls:AutoCompleteBox>
The Autocompletebox have got a property : TextBoxStyle where you can chose the style of the textbox.
Or you can do that in the property Style like that :
<UserControl.Resources>
<Style TargetType="TextBox" x:Key="TextboxStyle2">
<Setter Property="MaxLength" Value="74" />
<Setter Property="Width" Value="300" />
</Style>
<Style TargetType="controls:AutoCompleteBox" x:Key="TextBoxStyle">
<Setter Property="TextBoxStyle" Value="{StaticResource TextboxStyle2}" />
<Setter Property="IsTextCompletionEnabled" Value="True" />
</Style>
</UserControl.Resources>
/*...*/
<controls:AutoCompleteBox Name="Titre" Style="{StaticResource TextBoxStyle}"/>
But i don't know how to add the shadow. Try the others properties. =)
Edit :
To change background, there is already some tutoriels.
how to separate the background image in wpf textbox?
Exemple :
<Style TargetType="TextBox" x:Key="TextboxStyle2">
<Setter Property="MaxLength" Value="74" />
<Setter Property="Width" Value="300" />
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="../../../Ressources/Icones/Find_5650.ico" Stretch="None" AlignmentX="Left" AlignmentY="Top" />
</Setter.Value>
</Setter>
</Style>

How to inherit XAML style and override property of child element?

we just got started with XAML and are still fighting with basic issues:
Coming from CSS we'd like to define a generic button style with custom control template and then have a second style inherit everything from the first style using "basedon. This second style should then override properties such e.g. "foreground color" (which works) but also properties of child elements within our custom template such as the "background color" of e.g. an included border element etc. (which doesn't work).
What's the general approach to go about things like this? How far can we go with cascading styles?
Cheers!
You can use an inherited style with no key reference:
<Grid>
<Grid.Resources>
<!-- Definition of default appearance of a button -->
<Style TargetType="Button" x:Key="Default">
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="FontFamily" Value="Segoe Black" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontSize" Value="32pt" />
<Setter Property="Foreground" Value="#777777" />
</Style>
<!-- Define general style that based is base on the default style of the button without a key reference-->
<Style TargetType="Button" BasedOn="{StaticResource Default}"/>
<!-- In sub style override the properties you need -->
<Style BasedOn="{StaticResource Default}" TargetType="Button" x:Key="SubButton" >
<Setter Property="FontSize" Value="8pt" />
</Style>
</Grid.Resources>
<Button Content="Main" Height="51" HorizontalAlignment="Left" Margin="154,72,0,0" Name="button1" VerticalAlignment="Top" Width="141" />
<Button Content="Sub" Style="{StaticResource SubButton}" Height="51" HorizontalAlignment="Left" Margin="154,162,0,0" Name="button2" VerticalAlignment="Top" Width="141" />
</Grid>
I have (In my WPF application) default (base) styles defined in ResourceDictionary in App.xaml (in startup project). For example for button as follows.
<Style TargetType="Button">
<Setter Property="Margin" Value="5"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="FontSize" Value="16"/>
</Style>
In all views I use (by default) this general style (automatically inherited)! When I need to change or add some property in default style (defined in App.xaml) I create new style based on default style.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<!-- change -->
<Setter Property="Margin" Value="10" />
<!-- add -->
<Setter Property="Foreground" Value="Red" />
</Style>
When I need hide or strongly redefined default style (in some view) I create new style (based on nothing).
<Style TargetType="Button"/>
You can, of course, continues in inheritance in App.xaml or in specific view. You can based new named style on default style and use new style by name. For example RedButton and GreenButton style.
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="RedButton">
<Setter Property="Foreground" Value="Red" />
</Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}" x:Key="GreenButton">
<Setter Property="Foreground" Value="Green" />
</Style>
Etc...
NOTE: instead define your style in App.xaml you can use standalone library (dll) with styles only and ResourceDictionary from your library to App.xaml ResourceDictionary.MergedDictionaries.
The standard approach to making a customizable control template is to use TemplateBinding in the template to bind to properties of the control, and then to set those properties in the child styles.
For example, this creates a button template with a Border control, and binds the Background of the Border to the Background property of the Button. By setting the Background property of the Button in other styles, it changes the Background property of the Border.
<StackPanel>
<StackPanel.Resources>
<Style x:Key="BaseButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<ContentPresenter/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="BlueButtonStyle" TargetType="Button"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="Blue"/>
</Style>
<Style x:Key="RedButtonStyle" TargetType="Button"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="Red"/>
</Style>
</StackPanel.Resources>
<Button Style="{StaticResource RedButtonStyle}">Red</Button>
<Button Style="{StaticResource BlueButtonStyle}">Blue</Button>
</StackPanel>
Many of the properties on Control are intended to be used in control templates, and won't affect other behavior if they are changed. They are BorderBrush, BorderThickness, Background, Padding, HorizontalContentAlignment, and VerticalContentAlignment.

WPF UserControl Style

I want to set the background property of all the usercontrols of my project.
I tried with
<style TargetType={x:Type UserControl}>
<setter property="Background" Value="Red" />
</style>
It compiles but didn't work.
¿Any Idea?
Thanks!
You can only set a a style to a specific class, so this will work (create a UserControl object, not very useful):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>
But this doesn't (Create a class derived from UserControl):
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
What you can do is either explicitly set the style using the Style property:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content" Style="{StaticResource UCStyle}"></l:MyUserControl>
</Grid>
or create a style for each derived class, you can use BasedOn to avoid duplicating the style content:
<Window.Resources>
<Style TargetType="{x:Type UserControl}" x:Key="UCStyle">
<Setter Property="Background" Value="Red" />
</Style>
<Style TargetType="{x:Type l:MyUserControl}" BasedOn="{StaticResource UCStyle}" />
</Window.Resources>
<Grid>
<l:MyUserControl Name="control" Content="content"></l:MyUserControl>
</Grid>
I think you're missing some double quotes:
Try this:
<Window.Resources>
<Style TargetType="{x:Type UserControl}">
<Setter Property="Background" Value="Red" />
</Style>
</Window.Resources>
<Grid>
<UserControl Name="control" Content="content"></UserControl>
</Grid>

Resources