How access embedded control in style from style trigger - c#

I want to create style that can change embedded in him controls, like here I want to change "Source" of "ImageIco" but I get errors. Is it possible to make it inside style? Because all examples what I see use additional code or writing additional code in window itself.
Problematic part:
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="IcoImage" Property="Source" Value="{DynamicResource InfoIco.Red}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="IcoImage" Property="Source" Value="{DynamicResource InfoIco.White}"/>
</Trigger>
</Style.Triggers>
All style code:
<Style BasedOn="{StaticResource {x:Type Button}}"
TargetType="{x:Type Button}"
x:Key="RedsInfoButton">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}">
<Image Name="IcoImage"
Source="{DynamicResource InfoIco.White}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
</Style.Setters>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="IcoImage" Property="Source" Value="{DynamicResource InfoIco.Red}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter TargetName="IcoImage" Property="Source" Value="{DynamicResource InfoIco.White}"/>
</Trigger>
</Style.Triggers>
</Style>
<BitmapImage x:Key="InfoIco.White" UriSource="/WPFDesign/Data/Images/InfoWhite.ico"/>
<BitmapImage x:Key="InfoIco.Red" UriSource="/WPFDesign/Data/Images/InfoRed.ico"/>

Related

Changing Foreground for IsMouseOver anf IsPressed is not working in custom style

No matter what I try I can't set get the trigger IsMouseOver and IsPressed to change the Foreground.
I have been trying to alter it in the Button itself.
<Button (STUFF HERE)>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Button>
I have been trying to look it up, but I am pretty amateur with XAML.
here the general layout for styling controls:
<Button Content="OK">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers >
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
If you want to reuse the style, then save it to a resourcedictionary as a named style and you can refer to it on your controls
You have to create a style where you put the Triggers. Add this style to any resource dictionary in scope, e.g. the Window.Resources or the application resources if you want to reuse it across the application. If you omit the x:Key, you make it implicit and therefore apply to all Buttons in scope.
<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
Then reference that style in the Button.
<Button Style="{StaticResource MyButtonStyle}" .../>
Alternatively, you could also directly assign the style to the Button if it is the only one.
<Button Content="Styled">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="#FF373737"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="#FF4D4D4E"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Note that while this works for the Foreground property, it does not for properties like Background as they are defined in the ControlTemplate triggers which take precedence over a style. In order change those, you have to copy and adapt the Button ControlTemplate.
Update for your comment. Maybe you understand the Foreground property wrong. It is used for the text color of the content, not the color of the button itself. The "blue-ish" tint is determined by the Background property and as stated above, you have to edit the ControlTemplate for that.
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FF373737"/>
<SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
<SolidColorBrush x:Key="Button.Pressed.Background" Color="#FF4D4D4E"/>
<SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
<SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
<SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
<SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Button default style not applied if Triggers added

I defined a default style for all my application Buttons in App.xaml :
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="14"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border
x:Name="Border"
CornerRadius="2"
BorderThickness="1"
Background="{StaticResource WindowBorderColor}"
BorderBrush="{StaticResource WindowBorderColor}">
<ContentPresenter Margin="2" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="{StaticResource InactiveBackgroundColor}"/>
<Setter Property="Foreground" Value="{StaticResource InactiveForegroundColor}"/>
<Setter Property="Opacity" Value="0.5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource HeaderButtonOverColor}"/>
<Setter Property="Foreground" Value="{StaticResource HeaderForeHighlightColor}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="{StaticResource HeaderButtonPressedColor}"/>
<Setter Property="Foreground" Value="{StaticResource WindowForeColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But when I want to add a Trigger to my Button, the default style is not taken in account anymore :
<Button Content="{x:Static p:Resources.Delete}" Click="DeleteMacro_Click" Margin="3" >
<Button.Style>
<Style TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding MacroLeft.Name, Mode=OneWay}" Value="">
<Setter Property="Button.IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
I found that link, so I added TargetType="{x:Type Button}" in my WPF, but nothing changed.
Why is the default style not taken in account, and how can I solve that, without creating another specific style in my app.xaml?
You can make the styles defined in app.xaml as base in the following way
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
</Style>
</Button.Style>

WPF Material Design Raised Button Hovered state

I'm trying to recreate a material design look & feel for a button. For the focused (hovered) state the guidelines say to make a 12 % #000000 shade over the button. I was wondering how this could be achieved in WPF.
I've been looking around a good option would be to add a non-hittable rectangle over the button with a 12 % opacity and a color of #000000. I want to implement this as a style, but I have no idea how to do that.
My style looks like this at moment:
<Style x:Key="MaterialRaisedButton" TargetType="ToggleButton">
<Setter Property="Padding" Value="8 0"/>
<Setter Property="Margin" Value="8 6 8 6"/>
<Setter Property="Height" Value="36"/>
<Setter Property="MinWidth" Value="64"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="{StaticResource MaterialSecondaryColorBrush}"/>
<Setter Property="Effect" Value="{StaticResource z-depth2}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Grid>
<Rectangle RadiusX="4" RadiusY="4" Fill="#000000" Opacity="0.12"/>
<Border CornerRadius="4" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource Material12Black}"/>
</Trigger>
</Style.Triggers>
</Style>
If there are any other methods of doing this, I'm all ear as well :)
In the fill of the rectangle you can specify opacity in the hex color like #00000000, the first two values are the opacity. So 12% would be #1e000000. The following will show .5 opacity rectangle when mouse is over other wise opacity is 0.
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value=".5"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Opacity" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
Update:
If anybody wants to reuse the code for a material-like button, the code is below. I used the ripple effect from this stackoverflower along with the shadows from this source. Hopefully this can help others recreating Material design without the toolkit :)
<Style x:Key="MaterialRaisedButton2" TargetType="Button">
<Setter Property="Padding" Value="8 0"/>
<Setter Property="Margin" Value="8 6 8 6"/>
<Setter Property="Height" Value="36"/>
<Setter Property="MinWidth" Value="64"/>
<Setter Property="Foreground" Value="{StaticResource NormalTextBrush}"/>
<Setter Property="Background" Value="{StaticResource MaterialSecondaryColorBrush}"/>
<Setter Property="Effect" Value="{StaticResource z-depth2}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<cons:RippleEffectDecorator Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" Background="{TemplateBinding Background}" HighlightBackground="#1e000000" Grid.Row="0" Grid.Column="0" Panel.ZIndex="0">
<Grid>
<Rectangle RadiusX="4" RadiusY="4" Fill="#1e000000" Panel.ZIndex="1">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.12"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="false">
<Setter Property="Opacity" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</cons:RippleEffectDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="#1FFFFFFF"/>
<Setter Property="Foreground" Value="#42FFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>

How to get rid of the default blue color on hover over a button?

I've declared a style as follows.
<Style x:Key="RightButtonStyle"
TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="BlueViolet"></Setter>
</Trigger>
<Trigger Property="IsMouseOver"
Value="False">
<Setter Property="Background"
Value="Yellow" />
</Trigger>
</Style.Triggers>
</Style>
My button using the style does obey only the yellow part. For some reason it still gets bluish (default hover-over color) and not blue-violetish on hover. What am I missing? There are no other setters or styles that I'm aware of.
It's still using the default button template. You need to override it.
<Style Key="RightButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="BlueViolet"></Setter>
</Trigger>
<Trigger Property="IsMouseOver" Value="False">
<Setter Property="Background" Value="Yellow" />
</Trigger>
</Style.Triggers>
</Style>

WPF style button

I've tried to change style for mouseover event.
Here's my styles code:
<Window.Resources>
<Style x:Key="NavigationButton"
TargetType="{x:Type Button}">
<Setter Property="Background" Value="#295fa6"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
and I used it in that way:
<Button x:Name="test"
Grid.Column="0""
Style="{StaticResource NavigationButton}">
<Image Source="Assets/imaaa.png" />
</Button>
and mouseover still has default color
you need to modify the ControlTemplate. To remove the default behaviour on the Button.
<Style x:Key="NavigationButton"
TargetType="{x:Type Button}">
<Setter Property="Background" Value="#295fa6"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="#295fa6">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>

Categories

Resources