UWP Xaml : Container style that applies to children - c#

Let say I want to style a grid background like that :
<Page.Resources>
<Style x:key="MainGridStyle" TargetType="Grid">
<Setter Property="Background" Value="Blue" />
</Style>
</Page.Resources>
How can I make all TextBlocks inside that MainGridStyle Foreground=White through that Style?
Thanks

This works in WPF at least:
<Style x:key="MainGridStyle" TargetType="Grid">
<Setter Property="Background" Value="Blue" />
<Setter Property="TextElement.Foreground" Value="White" />
</Style>

Related

Adding one WPF style property kills all other style properties

I've a style for my WPF buttons, defined in the main window:
<Window.Resources>
<Style TargetType="Button">
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="FontSize" Value="12" />
<Setter Property="Foreground" Value="#FFFFFF" />
<Setter Property="Background" Value="#3fa9f5" />
...
</Style>
</Window.Resources>
In an UserControl, I want to set the content and the background depending on a binding:
<Button.Style>
<Style TargetType="Button">
<Setter Property="Content" Value="Text123" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=myControl, Path=IsHidden}"
Value="true">
<Setter Property="Content" Value="TextABC" />
<Setter Property="Background" Value="#ff1d25" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
The problem: The button in the UserControl looses all other properties it gets from the main window style (color, width, margins, ...).
I tried to let the UserControl button's style know the parent style via
BasedOn="{StaticResource {x:Type Button}}"
but with no result.

Changing Windows.Ribbon background color

I am working with the System.Windows.Ribbon in my project. I am also using some other libraries like AvalonDocking,... What I want to do is create my own themes inside the application so that the user can select the prefered theme.
The problem is that I don't get the RibbonTab to change to the correct colors. When I change the ribbon background color the RibbonTab color changes also. But I want to change it seperatly
Does anybody have any experience with changing the layout of the System.Windows.Ribbon?
This is what I tried before:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock">
<SolidColorBrush x:Key="WindowBrush" Color="Black"/>
<Style TargetType="{x:Type Ribbon}">
<Setter Property="Background" Value="#444444" />
<Setter Property="Foreground" Value="White" />
</Style>
<Style TargetType="{x:Type RibbonTab}">
<Setter Property="Height" Value="88" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Background" Value="Black" />
</Style>
<Style TargetType="{x:Type xcad:DockingManager}">
<Setter Property="Background" Value="#444444" />
<Setter Property="Foreground" Value="White" />
</Style>
</ResourceDictionary>
As you can see, the RibbonTab is not black like specified inside the ResourceDictionary

Bind to Style Setter from a different Style

how do I go about binding the Foreground Colour of one Style setter to the Fill Colour on another Style Setter, it should be the same object type. This is the code I have got below!
Getting these errors:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'ElementName=MenuItemPath'. BindingExpression:Path=Fill;
DataItem=null; target element is 'TextBlock' (Name=''); target
property is 'Foreground' (type 'Brush')
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{Binding ElementName=MenuItemPath, Path=Fill}" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="#FF22252C" />
<Setter Property="Height" Value="25" />
<Setter Property="Width" Value="25" />
<Setter Property="Stretch" Value="Uniform" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type RadioButton}}, Path=IsChecked}" Value="True">
<Setter Property="Fill" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
Personally I would create a separate Resource for storing the brush color, and reference it from both locations.
<SolidColorBrush Color="#FF22252C" x:Key="MenuFillColor" />
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="{StaticResource MenuFillColor}" />
...
</Style>
<ControlTemplate x:Key="MenuItem" TargetType="RadioButton">
<ControlTemplate.Resources>
<Style TargetType="Path" x:Name="MenuItemPath">
<Setter Property="Fill" Value="{StaticResource MenuFillColor}" />
...
</Style>
</ControlTemplate.Resources>
</ControlTemplate>
That said, I've never actually tried binding to another Style's Setter.Value property... it might be possible assuming everything was the same scope. You look like you may have different scopes since you are using <ControlTemplate.Resources> to limit the scope of your MenuItemPath style to just that ControlTemplate. But personally I would not attempt it, and would assume any requirement that needed something like this could also be done some better way :)
It is not possible to access outer property of another style in wpf and that's why you have got binding error. Rather you can declare a color in your resources and from where you can access it.
I was making it more complicated than need be, I just added a DataTrigger which fixed the issue:
<Style x:Key="MenuItemName" TargetType="TextBlock">
<Setter Property="Foreground" Value="Black" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=MenuItemRadio}" Value="True">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>

WPF :Material Design + dragablz tabItem header style

I am working in WPF with the MaterialDesign Toolkit and Dragablz.
I encountered a problem while trying to style a TabablzControl.
I already have style for the windows default TabControl and TabItem header, as shown in the picture:
http://i.imgur.com/2anl5rl.png
But when I change the default tabControl to TabablzControl, it turns into this:
http://i.imgur.com/bhaaMVy.png
Here are the window.resources:
<Style x:Key="mdTabControl" TargetType="TabControl">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
<Setter Property="Foreground" Value="{DynamicResource MaterialDesignBody}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Margin="1,0,1,0" CornerRadius="3 3 0 0">
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center"
HorizontalAlignment="Center"
ContentSource="Header" Margin="10,2,10,2"
RecognizesAccessKey="True">
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource SecondaryAccentBrush}" />
<Setter Property="Foreground" Value="{StaticResource SecondaryAccentForegroundBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueMidBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueMidForegroundBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="{StaticResource PrimaryHueDarkBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryHueDarkForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The error appears when I change the mdTabControl style targetType to:
TargetType="dbz:TabablzControl"
I want to keep the style I set to the TabControl, but with the added functionality of the TabablzControl
Any help will be appreciated
First thing to note, which is a general WPF characteristic, you are not using style inheritance correctly.
As you are using Material Design with Dragablz, if you are restyling the tab control itself, you must inherit from the Material Design style in the Dragablz assembly using BasedOn:
<Style x:Key="mdTabControl" TargetType="TabControl" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}">
<Setter Property="TextElement.Foreground" Value="{DynamicResource MaterialDesignBody}"/>
<Setter Property="Background" Value="{DynamicResource MaterialDesignPaper}"></Setter>
</Style>
Again, with the tab header itself, you need to inherit from the relevant style:
<Style x:Key="mdTabHeader" TargetType="{x:Type TabItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
. . .
</Style>
Note, that (depending you your App.xaml setup) you probably need to make sure the correct resource dictionary is included in the same XAML file. For example a more complete XAML might be:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/materialdesign.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="NormalTabItemStyle" TargetType="{x:Type dragablz:DragablzItem}" BasedOn="{StaticResource MaterialDesignDragableTabItemStyle}">
<Setter Property="Width" Value="280" />
<Setter Property="Padding" Value="1" />
</Style>
. . .
</ResourceDictionary>
</Window.Resources>
Finally, as you are changing the TabItem style, you either need to the TabablzCOntrol style the correct style, or you could use it where you actually declare the TabablzControl itself:
<dragablz:TabablzControl ItemContainerStyle="{StaticResource mdTabHeader}" />
A good example of all this in action is in the SidePanels project in the demo solution at: https://github.com/ButchersBoy/DragablzSamplez
<Style TargetType="{x:Type dragablz:TabablzControl}" BasedOn="{StaticResource MaterialDesignTabablzControlStyle}"/>

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.

Categories

Resources