WPF change Image when mouse hover on button - c#

I'm trying to change the image when mouse is over a button, but it's not working here is what am trying to do :
<Button x:Name="Play" Content="" ClickMode="Press" BorderThickness="0" UseLayoutRounding="True" Height="120" Width="224">
<Button.Background>
<ImageBrush ImageSource="Resources/Play 1.gif"/>
</Button.Background>
<Button.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="ImageBrush.ImageSource" Value="Resources/Play 2.gif"></Setter>
</Trigger>
</Button.Triggers>
</Button>
But this gives me this error : Triggers collection members must be of type EventTrigger.
How would I make it work?

It's correct - you can only put EventTriggers in there. You need to move your Trigger into the button's Style:
<Button x:Name="Play" Content="" ClickMode="Press" BorderThickness="0" UseLayoutRounding="True" Height="120" Width="224">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Resources\Play 1.gif"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="..\Resources\Play 2.gif"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
Something like that, I think (haven't tested it).
EDIT: This switches between the correct images, but it doesn't work correctly (it starts off with Play 1.gif, transitions to Play 2.gif, but then transitions to the button's underlying colour). I think you'll have to override the button's ControlTemplate to prevent this from happening, as suggested in the comments.

<Window x:Class="Image_ChangeOnHover"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Image_ChangeOnHover" Height="300" Width="300">
<Grid>
<Image Stretch="None" Margin="10">
<Image.Resources>
<Style TargetType="{x:Type Image}">
<!-- Default image -->
<Setter Property="Source" Value="/Resources/Off2.png"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Hover image -->
<Setter Property="Source" Value="/Resources/On.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Resources>
</Image>
</Grid>
</Window>

Related

Why isnt my button using the style I created?

So I decided to try to give a button a custom style.
Yet when I assign it the Style it wont use it, why is this?
I tried creatinga button with a textbox, image and a ellipse with a label on that too.
I want the button to change color when I hover over it but its making my button disappear.
Window resources
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ControlTemplate.Triggers>
<Trigger Property="Background" Value="#272727">
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And then the button
<Button Background="Transparent"
Style="{StaticResource MenuButton}"
Height="25"
BorderThickness="0">
<StackPanel Orientation="Horizontal">
<Image Source="Resources/earth-globe.png"
Height="20"
Width="20"
HorizontalAlignment="Left"
Margin="0,0,5,0"
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="Fant"/>
<Label Content="Websites"
Foreground="White"
VerticalAlignment="Center"
Width="100"
Height="24"/>
<Grid HorizontalAlignment="Right" Height="20" Width="20">
<Ellipse Width="20"
Height="20"
Fill="#555555"
Margin="0,0,0,0">
</Ellipse>
<TextBlock Text="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="12"
TextAlignment="Center"
Foreground="White"/>
</Grid>
</StackPanel>
</Button>
You do not want to put that style in the template portion of the style because a template is used for customizing the full control look (i.e. making a button a circle) and a way of giving the developer more flexibility over styling. What you could do is make a style that is applied to the button. Instead try this:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#272727" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
If you did want to modify the template property though, also a valid approach you need to add a <ContentPresenter />. See the below example:
<Window.Resources>
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter />
<ControlTemplate.Triggers>
<Trigger Property="Background" Value="#272727">
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Gray"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
However, with the minimal styling you have it seems like a poor use case to modify the template and I would recommend the first approach.
Add missing ContentPresenter to your DataTemplate.
<Style x:Key="MenuButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter /> <!--This thing was missing-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="RED" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

How to change the image of a button when a textbox is empty in WPF?

I want to create a SearchBox and currently my code looks like below. I tried to change the ImageSource of the ImageBrush tag when the text box is empty but I don't know to bind the Text property from the Textbox properly. I want my SearchBox to look like this:
When the SearchBox is empty the button must to show the search image and when the SearchBox is not empty the button must to show the clear search image. Can anyone hepl me with this?
<TextBox Name="SearchTextBox" />
<Button Grid.Column="0" Style="{DynamicResource NoChromeButton}" BorderThickness="1"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Click="Search_Click" Panel.ZIndex="1">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border>
<Grid>
<ContentPresenter />
<Grid x:Name="StatusPanel" Background="Black" Opacity="0"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="StatusPanel" Property="Opacity" Value="0.1"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="StatusPanel" Property="Opacity" Value="0.3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
<Button.Content>
<Rectangle x:Name="aaa" >
<Rectangle.Fill>
<ImageBrush ImageSource="pack://application:,,,/AssemblyName;component/Resources/Img1.png" />
</Rectangle.Fill>
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}" >
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=SearchTextBox, UpdateSourceTrigger=PropertyChanged}" Value="0" >
<DataTrigger.Setters>
<Setter Property="Fill">
<Setter.Value>
<ImageBrush ImageSource="pack://application:,,,/AssemblyName;component/Resources/Img2.png" />
</Setter.Value>
</Setter>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Button.Content>
</Button>
you are close. instead of setting <Rectangle.Fill> locally, use Style setter:
<Rectangle x:Name="aaa" >
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}" >
<Setter Property="Fill">
<Setter.Value>
<ImageBrush ImageSource="pack://application:,,,/AssemblyName;component/Resources/Img1.png" />
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Text.Length, ElementName=SearchTextBox}" Value="0" >
<DataTrigger.Setters>
<Setter Property="Fill">
<Setter.Value>
<ImageBrush ImageSource="pack://application:,,,/AssemblyName;component/Resources/Img2.png" />
</Setter.Value>
</Setter>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
it is necessary because Trigger cannot override local value

change background toggle button

I try to change the background of a toggle button everytime when it is checked or not,using 2 pictures. At runtime, the toggle button is simple and I don't see any image. This is my code:
<Canvas Height="25" Name="canvas1" Width="186" Background="White">
<ToggleButton Name="toggle1" Height="25" Padding="0" Width="27" Canvas.Left="131" Canvas.Top="0" BorderBrush="{x:Null}" Foreground="{x:Null}">
<ToggleButton.Resources>
<Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
Multiple things we can point here.
Firstly you're specifying the Style in ToggleButton.Resources with a x:Key. Thus it's not implicitly set. Setting a Style in resources of the item for which it applies in it's own scope is kinda weird. Rather just apply the Style directly as <ToggleButton.Style>.
Next, when working with Style.Triggers, make it a practice to specify a default Setter. This will prevent some headache for you. Also now instead of having two triggers for IsChecked=False/True, you only need one trigger as the other Background can be set as default.
Finally it seems like all you need from the ToggleButton is the IsChecked property and switch an Image. So just override the Template and provide a simple one yourself. This way you assure the behavior to stay consistent in all version of the OS and not rely on internal default template's working nicely for your customization(which wouldn't work in Windows-8 btw, what you're trying here for IsChecked=True due to internal overrides in default ControlTemplate)
So putting this all together we get:
<Style x:Key="MyToggleButtonStyle"
TargetType="ToggleButton">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png"
Stretch="Uniform"
TileMode="None" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked"
Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png"
Stretch="Uniform"
TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
and apply it to your ToggleButton
<ToggleButton Name="toggle1" Height="25" Padding="0" Width="27" Canvas.Left="131" Canvas.Top="0" BorderBrush="{x:Null}" Foreground="{x:Null}" Style="{DynamicResource MyToggleButtonStyle}">
you can ofc remove the Key in the Style and make it implicitly apply to "all" ToggleButton's within the scope of the Style definition if you choose to.
Can you check if the build action for your images is Embedded Resource please?
Define the style directly for your togglebutton like below. it should fix your issue:
<ToggleButton>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image2.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="/WpfApp;component/Images/image1.png" Stretch="Uniform" TileMode="None" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
You should remove the x:Key and it will work.

Glow effect on MouseEnter WPF

I'm new in WPF(c#). I need make a glow effect around image control using triggers. How can I do make glow effect on mouse-enter event?
I want to use your answer i my style.
My effect is:
<DropShadowEffect x:Key="MyEffect" ShadowDepth="0" Color="Blue" Opacity="1" BlurRadius="20"/>
I see many links but they don't work.
To add glow to Image control you need to set Effect to your DropShadowEffect when IsMouseOver=True, something like this:
<Image Source="/WpfApplication1;component/myimage.png">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="Blue" Opacity="1" BlurRadius="20"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
If you want to reuse your effect, you must capture IsMouseOver trigger and set Control.Effect property to what you have defined in your resources.
<Button Width="100" Content="Hello Glow" >
<Button.Style>
<Style>
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="True">
<Setter Property="Button.Effect" Value="{StaticResource MyEffect}" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
for this, you must place you effect in recourses of current page/window/usercontrol
<Window.Resources>
<DropShadowEffect x:Key="MyEffect" ShadowDepth="0" Color="Blue" Opacity="1" BlurRadius="20"/>
</Window.Resources>

How to create a custom control with both an enabled and disabled visual state and a content presenter

I'm new to making custom WPF controls so I'd really appreciate a little help and some explanation. Here's the situation:
I'm trying to make a custom control with the following traits:
The control must have a content presenter.
The control must have either a disabled/enabled visual state, or be tri-state, (unstarted/inprogress/finished)
The control should if possible have support for an animation based on the state (enabled/disabled)
Ideally I'd like something that I can stack nicely like this, so any suggestions for how to do this would be appreciated.
I am using Blend 3 if anyone wants me to use VSM stuff, but I have no experience with the blend 3 extension so I'd need a little guidance and explanation if possible. Thank you all of your time!
In WPF it's very easy to change the appearance and behaviour of (standard)controls. In this case you can use a checkbox as a starting point.
First make a copy of the control's template:
"img43.imageshack.us/img43/1694/36338162.png"
You will see the folowing:
"img194.imageshack.us/img194/374/89409336.png"
Now group the BulletDecorator into a Grid, move then ContentPresenter to that Grid and remove the BulletDecorator and ist children.
"img9.imageshack.us/img9/7739/74247109.png"
At this point you have a checkbox like control that only has a ContentPresenter.
Now you can use the trigger tab to set is behaviour.
"http://img43.imageshack.us/img43/3675/15279262.png"
The code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
x:Class="WpfApplication1.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480" mc:Ignorable="d">
<Window.Resources>
<SolidColorBrush x:Key="CheckBoxFillNormal" Color="#F4F4F4"/>
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F"/>
<Style x:Key="EmptyCheckBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="1" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckRadioFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="14,0,0,0" SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Background" Value="{StaticResource CheckBoxFillNormal}"/>
<Setter Property="BorderBrush" Value="{StaticResource CheckBoxStroke}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource EmptyCheckBoxFocusVisual}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid x:Name="grid" Width="64.42" Height="15.96">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="13,0,0,0" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" TargetName="grid" Value="#FF07FF00"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" TargetName="grid" Value="Red"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Background" Value="#FFFFDD00"/>
<Setter Property="Background" TargetName="grid" Value="#FFFFF400"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<CheckBox HorizontalAlignment="Left" Margin="117,72,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" Margin="117,91.96,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True" IsChecked="{x:Null}"/>
<CheckBox HorizontalAlignment="Left" Margin="117,111.92,0,0" Style="{DynamicResource CheckBoxStyle1}" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True" IsChecked="True"/>
<CheckBox HorizontalAlignment="Left" Margin="209,72,0,0" VerticalAlignment="Top" Content="CheckBox" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" Margin="209,92.96,0,0" VerticalAlignment="Top" Content="CheckBox" IsChecked="{x:Null}" IsThreeState="True"/>
<CheckBox HorizontalAlignment="Left" VerticalAlignment="Top" Content="CheckBox" Margin="209,111.92,0,0" IsThreeState="True" IsChecked="True"/>
</Grid>
Was this any help to you?
Greetings,
Carl

Categories