WPF: Change a value from a template - wpf

I want a value which is inside a template to change while some trigger happens. I can't access it through the style trigger's for some reason. How do I achieve that?
example:
<Style TargetType="Button" x:Key="iconButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Margin="5">
<Ellipse Width="45" Height="45" Fill="White" Opacity="0"/>
<TextBlock Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center">hello</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--TODO - change the "opacity" of the ellipse.
Maybe binding is necessary? -->
</Trigger>
</Style.Triggers>
</Style>
I would like to change the opacity property of the ellipse (which is inside the style's template) while overing the button with the mouse.
How can this be achieved?

Instead of Style Triggers use ControlTemplate Triggers. Refer below code.
<Style TargetType="Button" x:Key="iconButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Margin="5">
<Ellipse Width="45" x:Name="EllipseControl" Height="45" Fill="White" Opacity="0"/>
<TextBlock Foreground="White"
HorizontalAlignment="Center"
VerticalAlignment="Center">hello</TextBlock>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="EllipseControl" Property="Opacity" Value="1"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Related

Why button color doesn't change on MouseOver

I don't understeand why this code doesn't work.
The button color is still default when I hover my mouse over it.
<Window>
<Window.Resources>
<Style x:Key="hover" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button
Width="144"
Height="58"
Margin="320,177,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Button"
Style="{StaticResource hover}" />
</Grid>
</Window>
it is necessary to modify the ControlTemplate to activate the IsMouseOver event like this :
<Button Width="144" Height="58" Margin="320,177,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Content="Button" >
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="1">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>

IsMouseOver Property on Button not working

I have this button and wanted to change the design if I hover over it with the mouse. It's not working and I'm not getting an error.
What am I doing wrong?
(I'm really new to WPF)
<Button MaxWidth="180"
Margin="5"
DockPanel.Dock="Top"
Padding="5"
FontSize="12"
Foreground="#1261AC"
FontWeight="SemiBold"
BorderBrush="Transparent">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Background="LightGray" BorderThickness="1" Padding="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#157ec4"/>
<Setter Property="Background" Value="#000000"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
The button itself is working but it is not chaning the color of the background or font.
(The colors in my example are just for testing)
The problem with your code is that you define the border-background to be gray.
Now you change the control background using a trigger.
However, the background that is set by the trigger is not yet related to the border background in your example.
I added a template binding that fixes this issue to you. Now the border in your template will always have the Background defined in your style, set by triggers or directly set in XAML.
PLEASE NOTE:
If you set the color in XAML by using <Button Background="Pink"/> this will overwrite the style and trigger attributes.
if you still want to overwrite the background property for a single button for some reason without overwritting the triggers you'll have to create a style based on the original style using the BasedOn Property:
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Propert="Background" Value="Yellow"/>
</Style>
try this piece of art:
ButtonStyle:
<Button Content="Hello there!"
MaxWidth="180"
Margin="5"
DockPanel.Dock="Top"
Padding="5"
FontSize="12"
Foreground="#1261AC"
FontWeight="SemiBold"
BorderBrush="Transparent">
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="HotPink"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="5" Background="{TemplateBinding Background}" BorderThickness="1" Padding="5">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
<Setter Property="Background" Value="Lime" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>

"Pushed" effect on button press

I have circular button as
XAML for that is,
<!--round button-->
<Style x:Key ="roundButtonTemplate" TargetType ="{x:Type Button}">
<Setter Property ="Margin" Value ="10,0,10,10"/>
<Setter Property ="Template">
<Setter.Value>
<ControlTemplate TargetType ="{x:Type Button}">
<Grid>
<Ellipse x:Name ="OuterRing" Width ="40" Height ="40" Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property ="IsPressed" Value ="True">
<Setter TargetName ="OuterRing" Property ="Height" Value ="30"/>
<Setter TargetName ="OuterRing" Property ="Width" Value ="30"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And I have applied it as,
<Button Style="{StaticResource roundButtonTemplate}" Click="button_Click" Background="#CC41B1E1" Width="42" Height="42" Margin="0,0,10,0">
<Image Height="24" Width="24" Source="/Images/add.png" />
</Button>
Now the problem is when I press the button only the circle shrinks but the image remains as it is. I want the whole button to shrink with image as well to give it a perfect "Pushed" effect.
Any idea what is getting wrong?
Instead of changing size to some fixed value in you template apply ScaleTransform to main Grid of your template
<ControlTemplate TargetType ="{x:Type Button}">
<Grid RenderTransformOrigin="0.5,0.5" x:Name="RootGrid">
<Ellipse x:Name ="OuterRing" Width ="40" Height ="40" Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property ="IsPressed" Value ="True">
<Setter TargetName="RootGrid" Property="RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.9" ScaleY="0.9"/>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
don't forget to set RenderTransformOrigin="0.5,0.5"

In Template, can I make a trigger change Path.Fill when Path is a ContentPresenter?

I have a button template, where ContentPresenter is actually a Path.
On MouseOver, I want to change the Path.Fill.
See the template:
<Style x:Key="spinButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Border x:Name="Bd" BorderThickness="0" Background="Transparent" CornerRadius="2">
<ContentPresenter HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="Bd" Value="#666666"/>
<Setter Property="Control.Foreground" Value="#999999"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the code that uses this template:
<RepeatButton Style="{StaticResource spinButtonStyle}">
<Path blah blah blah/>
</RepeatButton>
Now, in this case, that ContentPresenter is a Path. Is there any way to change the Path.Fill color in the XAML?
All you need to do now is bind the Path Fill property to your RepeatButton Foreground property:
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type RepeatButton}}}"

Change color of MenuItem on MouseOver

I want to change the color of a MenuItem at mouseOver. I need also rounded borders, an image and a textBox. When I set the style all is ok only the mouseOverEvent is doing anything, the background doesnot change. My code is:
<Style x:Key="BaseStyle" TargetType="MenuItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Background" Value="#0a99f3" />
</Trigger>
</Style.Triggers>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid>
<Border Name="MainBorder" BorderThickness="2,2,2,0" CornerRadius="8,8,8,8" Margin="0,0,1,0" BorderBrush="AliceBlue">
<Grid>
<TextBlock Text="Info" Margin="30,10,0,0" FontFamily="Arial" FontSize="14" FontWeight="Bold" />
<Image Width="15" Height="15" Source="menu.PNG" Margin="-100,0,0,0" />
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Hope anybody know what I am missing. Thanks!
You're overwritting the Template, but not using the Background Color anywhere in it so the value never gets applied.
Set the Background Color in your MenuItem Template
<ControlTemplate TargetType="{x:Type MenuItem}">
<Grid Background="{TemplateBinding Background}">
You are not binding the Background anywhere in your template so changing that property has no effect.

Resources