Change color of MenuItem on MouseOver - wpf

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.

Related

In Wpf how to avoid/disable mouse hover a button highlight color?

I wonder if there is a way to do it for all the future buttons and other controls or do i need to make a solution for each control/button ? And how to do it ?
I want to disable the mouse hove highlight.
<Button x:Name="btnTest" Content="Start Watching" HorizontalAlignment="Left" Margin="14,241,0,0" VerticalAlignment="Top" Width="109" RenderTransformOrigin="0.484,-0.066" Height="30" FontSize="16" Background="#FFFB0000" Click="btnTest_Click"/>
<TextBox HorizontalAlignment="Left" Height="30" Margin="14,175,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="644"/>
<Button Content="Browse" Margin="673,175,18,0" VerticalAlignment="Top" RenderTransformOrigin="-0.111,0.769" Height="30" FontSize="16"/>
Add it to your ResourceDictionary:
<Style TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And since Style has no key it will be on all the buttons
You'll need to create a style. if you want it to be applied through your whole app, you'll need to put it into your "app.xaml" file (within an application.Resources).
Bellow is an example of how to do it. I added some stuff like setters to illustrate that you can add properties, you could also add triggers and many things.
Not setting a "x:key" to your style will make them the default one (thus overriding the basic one), as the one below, if you wish to have a collection of styles, give them keys.
`<Style TargetType="{x:Type Button}">
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="0" />
<Setter Property="Cursor"
Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center">
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>`

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>

Changing the background of a WPF button to a solid color when mouse is rolled over? [duplicate]

My problem is that in WPF, whenever I try and change the colour of a button's background using triggers or animations, the default mouseover effect (of being grey with that orange glow) seems to take priority.
After extensive searches I'm clueless as to how to remove this effect.
This is similar to the solution referred by Mark Heath but with not as much code to just create a very basic button, without the built-in mouse over animation effect. It preserves a simple mouse over effect of showing the button border in black.
The style can be inserted into the Window.Resources or UserControl.Resources section for example (as shown).
<UserControl.Resources>
<!-- This style is used for buttons, to remove the WPF default 'animated' mouse over effect -->
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="border" Property="BorderBrush" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<!-- usage in xaml -->
<Button Style="{StaticResource MyButtonStyle}">Hello!</Button>
Just to add a very simple solution, that was good enough for me, and I think addresses the OP's issue. I used the solution in this answer except with a regular Background value instead of an image.
<Style x:Key="SomeButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<ContentPresenter />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
No re-templating beyond forcing the Background to always be the Transparent background from the templated button - mouseover no longer affects the background once this is done. Obviously replace Transparent with any preferred value.
You need to create your own custom button template to have full control over the appearance in all states. Here's a tutorial.
The Muffin Man had a very simple answer which worked for me.
To add a little more specific direction, at least for VS 2013:
Right-click the control
Select Edit Template => Edit a copy...
I selected 'Application' for where to save the style
From here you can directly edit App.xaml and see the intuitively named properties. For my purposes, I just set RenderMouseOver="False"
Then, in the MainWindow.xaml or wherever your GUI is, you can paste the new style at the end of the Button tag, e.g. ... Style="{DynamicResource MouseOverNonDefault}"/>
This Link helped me alot
http://www.codescratcher.com/wpf/remove-default-mouse-over-effect-on-wpf-buttons/
Define a style in UserControl.Resources or Window.Resources
<Window.Resources>
<Style x:Key="MyButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Then add the style to your button this way Style="{StaticResource MyButton}"
<Button Name="btnSecond" Width="350" Height="120" Margin="15" Style="{StaticResource MyButton}">
<Button.Background>
<ImageBrush ImageSource="/Remove_Default_Button_Effect;component/Images/WithStyle.jpg"></ImageBrush>
</Button.Background>
</Button>
If someone doesn't want to override default Control Template then here is the solution.
You can create DataTemplate for button which can have TextBlock and then you can write Property trigger on IsMouseOver property to disable mouse over effect. Height of TextBlock and Button should be same.
<Button Background="Black" Margin="0" Padding="0" BorderThickness="0" Cursor="Hand" Height="20">
<Button.ContentTemplate>
<DataTemplate>
<TextBlock Text="GO" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" TextDecorations="Underline" Margin="0" Padding="0" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property ="IsMouseOver" Value="True">
<Setter Property= "Background" Value="Black"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</Button.ContentTemplate>
</Button>
An extension on dodgy_coder's answer which adds support for..
Maintaining WPF button style
Adds support for IsSelected and hover, i.e. a toggled button
<Style x:Key="Button.Hoverless" TargetType="{x:Type ButtonBase}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#FFBEE6FD" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#BB90EE90" />
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="Selector.IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="LightGreen" />
</MultiTrigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="border" Property="Opacity" Value="0.95" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
examples..
<Button Content="Wipe On" Selector.IsSelected="True" />
<Button Content="Wipe Off" Selector.IsSelected="False" />
Using a template trigger:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="White"></Setter>
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Why my button is possible to click only if cursor position is in content or in the border

I have problem with my button style. And when the cursor is in the button is can't click (if is not in the content or in the border of the element.
My xaml code:
<Button Style="{StaticResource DataButton}" Content="OK" Command="{Binding OKButton}" MinWidth="72" Height="22" Margin="5" />
My static resource
<Style x:Key="DataButton" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="2" BorderBrush="#d6d6d6" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
How can I fix this the user can click on button whatever is in the button perimeter.
Remove <Setter Property="OverridesDefaultStyle" Value="True" /> from the code. As you have replaced the built in style of Button, it no longer recognizes the click action defined in the Theme.
You have overrided default style and set Alignment to Center. You can remove overrideDefaultStyle or remove alignment, or you can make your layout in the other way.

Setting WPF text backcolor with focus and image

WPF /MVVM Pattern
User control with multiple textboxes using validation attributes.
In the following style, everything works as intended- EXCEPT for those with a validation error, the Focused backcolor is not being set, due to the method used in the control template to set the error image.
If I remove the control template, the backcolor is set properly when focused if the validation error is set. With the template, backcolor is always white/default.
Any suggestions on the XAML required to have both - different backcolor when focused and the error image when validation fails?
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="1" />
<Setter Property="ToolTip" Value="{Binding Description}"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="LightYellow"/>
</Trigger>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<!--adds the error image and border, but also prevents background color change OnFocus-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border
BorderBrush="#d99" x:Name="textBorder" CornerRadius="4"
BorderThickness="2" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0"
Source="/Images/error.png" HorizontalAlignment="Right">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
You should check out the DependencyProperty precedence rules
What happens here is that the ControlTemplate you define overrides the Style.Triggers defined just before.
What you can do to make it work is to set the actual Style with appropriate Triggers directly inside of the ControlTemplate
Otherwise, as you've seen, WPF will just use the default template for a Grid.
The code should look like that:
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors).CurrentItem.ErrorContent}"/>
<!--adds the error image and border, but also prevents background color change OnFocus-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Style.Triggers>
<!-- The trigger about IsFocused should be here!
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="LightYellow"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Border
BorderBrush="#d99" x:Name="textBorder" CornerRadius="4"
BorderThickness="2" >
<ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
</Border>
<Image Name="ErrorImage" Width="24" Height="24" Margin="0,0,4,0"
Source="/Images/error.png" HorizontalAlignment="Right">
</Image>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>

Resources