I am making a little project, in which I am using data validation. Now I am trying to make styling for TextBox, when the input is not correct. I want to make a red border around the TextBox and a ToolTip with error message, which I return from C# code.
I started with making the red border. I wrote this in XAML:
<Window.Resources>
<Style x:Key="ErrorTemplate" TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red"></Setter>
<Setter Property="BorderThickness" Value="5"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
But if I write it like this, BorderThickness property is changing inner border thickness of the TextBox. With the code above, I get this:
Is there a way, to avoid this, and get something like this?
And in a way, that I can add that ToolTip, using the same Style.
EDIT:
Code of TextBox:
<TextBox
Grid.Row="1"
Grid.Column="3"
Margin="10px"
FontSize="14pt"
VerticalAlignment="Center"
Padding="5px"
Text="{Binding Path=Name, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Style="{StaticResource ErrorTemplate}">
<TextBox.DataContext>
<local:Data/>
</TextBox.DataContext>
</TextBox>
The blue border that you see is the border of the TextBox itself, which is light blue by default in its keyboard focused state. The border is 5 dips thick, because you explicitly set it in your provided ErrorTemplate style. The red line around it is the default error template of the TextBox.
In order to meet your requirements, create a style like below.
Set a general Margin of 5 dips to account for the border that is displayed on error, it could otherwise be cut off outside the container since it is just an overlay over the original TextBox and it is not resized.
Set an optional default tool tip for the non-error state.
Set an ErrorTemplate, which is a special template dedicated to the error state, where AdornedElementPlaceholder represents the original TextBox in the template.
Set a trigger that changes the tool tip text to the validation error in error state.
<Style x:Key="MyTextBoxValidationStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Margin" Value="5"/>
<Setter Property="ToolTip" Value="There is no error."/>
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<StackPanel>
<Border BorderBrush="Red" BorderThickness="5">
<AdornedElementPlaceholder/>
</Border>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
Apply the style to your TextBox using the Style property.
<TextBox Style="{StaticResource MyTextBoxValidationStyle}" ...>
Here is a sample screenshot of the result.
Related
I have a datagrid template column where I am changing the text color from code behind for textblock "MyTextBlockRotationVersion". I am trying to use the text color change to also change the background color of the cell so that when it goes from celltemplate to celleditingtemplate and vice versa the red background remains. Not sure why the trigger isn't turning the background red. Right now the text color changes but the background does not. I lose the color changes after it goes to celleditingtemplate and back to celltemplate.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="MyTextBlockRotationVersion" Text="{Binding RotationVersion, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextWrapping="Wrap" VerticalAlignment="Center" HorizontalAlignment="Center" MaxWidth="70"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsEditing" Value="True" />
</Trigger>
<Trigger x:Name="MyTextBlockRotationVersion" Property="Foreground" Value="Red">
<Setter Property="Background" Value="Red"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridTemplateColumn.CellStyle>
I don't think you can access the elements from within another DataTemplate (or ControlTemplate)
Also to access a specific element by name you want to use SourceName and not x:Name (x:Name names the trigger)
I've been banging my head over this all night. All I want to do is have a content control that can switch between showing two different buttons according to a boolean in the ViewModel.
Basically I have a task running in the background with a cancel button. Once you hit cancel and the task stops, the cancel button should change to a back button. These are two separate button elements, not just changing a single button's properties. I'm using MahApps TransitioningContentControl so I want to be able to use the transitions.
I would be amazing if this could mostly be done all in XAML. I really don't want to have to add a bunch of boilerplate code for what should be a simple thing.
Edit: Here's the snippet of code. There isn't much because I just deleted everything that wasn't working.
<Controls:TransitioningContentControl x:Name="CancelBackButtonControl" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Height="80">
<Canvas>
<Button x:Name="CancelButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_close}" BorderBrush="Black" Command="{Binding CancelCommand}"/>
<Button x:Name="GoBackButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_arrow_left}" BorderBrush="Black" Command="{Binding GoBackCommand}"/>
</Canvas>
</Controls:TransitioningContentControl>
There are a staggering amount of ways to accomplish this (that's the beauty of WPF); however, in my personal opinion, you would be working less "against the grain" if you simply use a control that derives from the ToggleButton, such as RadioButton, especially since you want it to be done all in XAML. An important thing is not to think of any of the controls by their visuals, but by how they function. I've done some incredible things with RadioButton before, so that's the first thing I'll demonstrate; however, the regular button approach is included in the second half of this answer.
Here are the complete examples of both approaches (RadioButton and Button), done completely in XAML:
Preview:
Code:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type RadioButton}" x:Key="FlatRadioButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="Background" Value="#FF346FD6"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="5,2,5,3"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF6696E9"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<RadioButton x:Name="BackButton" Content="Back">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<RadioButton x:Name="CancelButton" Content="Cancel" IsChecked="True">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
</Grid>
</Window>
Most of the resource style code is visual styling and templating, focused on making radio buttons look like regular buttons, so it's not of great importance. The areas we'll focus on are Triggers. You'll notice that in the resource style, I ensure that when a RadioButton gets checked, it collapses. However, in the local style of each button, I ensure that when the other RadioButton gets checked, it makes the current RadioButton visible. This has to be done in the local style, since we need to pass the ElementName into the Binding. So, when a RadioButton gets checked, it collapses and makes the other RadioButton visible. You'll also note that I check the button I wish to hide by default. Obviously, you can wire that up with bindings.
Similar approaches may be applied to regular buttons:
Preview:
Code:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ToggleButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button x:Name="CancelButton" Content="Cancel">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button x:Name="BackButton" Content="Back">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
Here, instead of IsChecked, I'm working with IsFocused. You may accomplish a similar thing by working with the EventTrigger and Click event... but, there's more work. IsPressed may appear like a good candidate, but the problem is that once you press the button, the other one will appear almost instantaneously, and that one will have IsPressed set to true almost instantaneously. So, you'll end up with this cyclic behavior where it seems like nothing is happening. Note that I use Grid to place these buttons on top of each other, with the the one I want to be visible by default at the top, that way I don't have to worry about default visibility or focus. However, you may use any other panel, just set the Visibility of the button you want to hide by default to Collapsed.
If you don't want to work with multiple controls (two buttons in this case), you may also set the Content property of a button based on a condition through DataTrigger to display different text. You just have to ensure that you handle the Command appropriately.
Since you're asking for a XAML only way to switch the button in a content control based on a ViewModel property, how about this:
First define button style to route both buttons to the same event:
<Style x:Key="buttonClickButton" TargetType="Button">
<EventSetter Event="Click" Handler="Button_Click"/>
</Style>
Then define your content control style with a data trigger switching the content based on a ViewModel property called "IsCancelButton" (bool):
<Style x:Key="ButtonSwitchContentCtrl" TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding IsCancelButton}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Button x:Name="CancelButton" Style="{StaticResource buttonClickButton}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="80" Height="80" IsCancel="True" Content="Cancel Button" BorderBrush="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsCancelButton}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Button x:Name="GoBackButton" Style="{StaticResource buttonClickButton}"
HorizontalAlignment="Left" VerticalAlignment="Top"
Width="80" Height="80" IsCancel="True" Content="Go Back Button" BorderBrush="Black" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Then make your button(s) appear like so:
<ContentControl Style="{StaticResource ButtonSwitchContentCtrl}"/>
You can implement such functionality with just one Button (e.g. declared in XAML as Name="btnCancel") and simple code snippet in C# code-behind using Lambda-style event subscription like:
btnCancel.Click+=(s,e)=>{
if (btnCancel.Text=="Cancel")
{
// SOME CODE CORRESPONDING TO "CANCEL" CLICK EVENT
btnCancel.Text ="GoBack"
}
else
{
// CORRESPONDING TO "GoBack" CLICK EVENT
btnCancel.Text ="Cancel"
}
}
In case you want to use some graphic content (images) on the Button, then use Tag property of that Button instead of Text and also programmatically switch between images.
Couple other considerations: the business logic you have described could be implemented in XAML using DataTriggers (as other folks did), but instead of writing megaton of XAML for 2-Buttons solutions it would be reasonable to implement a single-button solution, either like this one, or using .NET ToggleButton Class (re: https://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.togglebutton%28v=vs.110%29.aspx); also, it could be a CheckBox control just properly styled.
In any way, you most likely will need the event handlers to do some actual job in addition to just changing the visual state of the Button, so that compact Lambda-style event subscription would be handy.
Hope this may help. Best regards,
I wanted to restyle my buttons to be more flat so I have created two styles; first for ToggleButton that derives from ToolBar.ToggleButtonStyleKey and second for Buttonthat derives from ToolBar.ButtonStyleKey.
It worked great - the buttons are now toolbar-like and flat. Second thing I wanted is to have Background property to be transparent when user hovers the cursor over the control. So to achieve that I defined a simple trigger that sets the Background to Transparent on IsMouseOver event. It worked for ToggleButton, however, the same trigger didn't work for Button(the background was not affected at all).
Does anyone know why this trigger works great for ToggleButton and does not work for Button? I did expect the same behavior since both styles are from the same family.
Below is the full code.
<Window x:Class="WpfButtonsTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="FlatToggleButton" TargetType="ToggleButton"
BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="FlatButton" TargetType="Button"
BasedOn="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<ToggleButton Style="{StaticResource FlatToggleButton}">
I am Toggle Button
</ToggleButton>
<Button Style="{StaticResource FlatButton}">
I am Button
</Button>
</StackPanel>
</Grid>
</Window>
I had a look using Snoop (a very handy program for inspecting WPF ) and it looks like the template which you're using as a basis, ToolBar.ButtonStyleKey, has a trigger which selects a solid Brush for the background of a Border element within the Button (in thise case when IsMouseOver is true).
Your local style trigger is successfully setting the background of the Button element to transparent (or rather, keeping it transparent), but the Border background is unaffected, so you'll still see the highlighting behaviour.
Border Background:
Button Background:
I think you'll have to define a ControlTemplate to get the button you're after, I've grabbed this from one of the ToolBar samples included in Kaxaml (a nice XAML editor). It's a reasonable facsimile of the Toolbar bas button style, with a few bits removed, it may behave as you want, or you might need to tweak it depending on your desired behaviour.
I've left the IsPressed trigger in place, you may want to remove it, or add additional triggers.
<Style x:Key="ToolBarButtonBaseStyle" TargetType="{x:Type ButtonBase}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border
x:Name="Border"
BorderThickness="1"
Background="Transparent"
BorderBrush="Transparent">
<ContentPresenter
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<!-- Additional triggers removed, e.g "IsMouseOver" -->
<!-- You may not want any at all -->
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="Border" Property="Background" Value="#E0E0E0" />
<Setter TargetName="Border" Property="BorderBrush" Value="#606060" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I see that the both FlatToggleButton and FlatButton styles already have Background as Transparent
<Setter Property="Background" Value="Transparent"/>
When the triggers is fired on IsMouseOver and set the Background again to Transparent you will not see any difference
So what you need to do is one of these options :
Change both styles so that the Background is something else than Transparent
Change the trigger so it sets the Background to something else than Transparent
I'm trying to customize my ToggleButtons so that when checked they say 'Yes' in green and when not checked, say 'No' in red.
I've created the following style which is sitting in my Styles resource dictionary.
<!-- ToggleButtons -->
<Style x:Key="YesNoToggleStyle" TargetType="ToggleButton">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="SpringGreen" />
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="Yes"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="Crimson" />
<Setter Property="Content">
<Setter.Value>
<TextBlock Text="No"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
This works ... sort of. If the ToggleButton is the last one of either value, then it displays correctly. All previous buttons with the same value are blank. The height was also shrinking, but I fixed that with the 'Height' Setter above the triggers. To illustrate, when a new record is being created it looks like:
and after I've clicked buttons 1, 2, and 3 and 1 again:
I originally had the style referenced from the surrounding grid:
<Grid>
...
<Grid.Resources>
<Style BasedOn="{StaticResource YesNoToggleStyle}" TargetType="{x:Type ToggleButton}" />
</Grid.Resources>
But changing that so each ToggleButton references the style individually (<ToggleButton Style="{StaticResource YesNoToggleStyle}" ... />) hasn't made a difference.
I looked at Customizing the toggle state of a toggle button in wpf, and Override ToggleButton Style where the effect is the same, but they talk about external images, and my issues is all within wpf.
I also looked at the second answer to: i want to change backcolor of toggle button when toggle button ischecked and viceversa in WPF but a) I only have the blend + sketchflow preview that comes with VS2012, and b) i'm a total noob with blend and can't get from Select the "Checked State" to Reset the Background Color instruction in the answer (plus i'd be surprised if this task requires the blend tool).
Can anyone show me what to do to get multiple ToggleButtons to use the same style properly?
This works for me. Somewhere in Dictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="YesNoToggleStyle" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Background" Value="Crimson" />
<Setter Property="Content" Value="No"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="SpringGreen" />
<Setter Property="Content" Value="Yes"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Note, that style is based on ToolBar.ToggleButtonStyle.
<Grid>
<Grid.Resources>
<ResourceDictionary Source="pack://application:,,,/Dictionary1.xaml"/>
</Grid.Resources>
<ItemsControl ItemContainerStyle="{StaticResource YesNoToggleStyle}">
<ToggleButton />
<ToggleButton />
<ToggleButton />
</ItemsControl>
</Grid>
try to replace Content property to ContentTemplate:
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="Yes"/>
</DataTemplate>
</Setter.Value>
</Setter>
In my case I wanted to have a "Locked" ToggleButton in a common dll defined and reused across my Apps.
Here's my result, which worked for me. Maybe someone find it useful (put this in a Resourcedictionary.xaml):
<BitmapImage x:Key="LockedLock"
UriSource="/...;component/Resources/Lock_closed_16p.png" />
<BitmapImage x:Key="OpenLock"
UriSource="/...;component/Resources/Lock_open_16p.png" />
<Style x:Key="LockButton"
TargetType="ToggleButton">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Source="{DynamicResource OpenLock }"
Width="12"
Height="12"
Name="contentimage" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton , AncestorLevel=1, Mode=FindAncestor }, Path=IsChecked}"
Value="True">
<Setter Property="Image.Source"
TargetName="contentimage"
Value="{DynamicResource LockedLock }" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
Credits to:
Setting Button's Content to <Image> via Styles
Setter Target Name not recognized
I have a datatemplate used for datagridtemplatecolumn
I am trying to show different image on mouse over in Image.
On mouse over, the cursor is changing but image is not changing.
<DataTemplate x:Key="MyDataTemplate" DataType="DataRowView">
<StackPanel Orientation="Horizontal" Background="Transparent">
<Image Margin="0,0,0,0" Width="50" Height="50" Source="{Binding Converter={StaticResource SetImgToDG}}" ToolTip="{Binding}" >
<Image.Resources>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Hover image -->
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Source" Value="C:\Images\Coil3.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Resources>
</Image>
</StackPanel>
</DataTemplate>
Is that binding creates the problem??
How to resolve it??
Your problem is that the initial source of the image is defined directly on the Source property of the image instance.
When there are multiple things that try to set the value of a dependency property, the framework has to decide which value to use.
In your case the value is being set directly on the image instance (locally) and also by a Trigger.
The local value will always win in this case, so nothing happens when the Trigger is activated.
If you set the initial value in the style instead, the Trigger will win when it tries to change the image source, and that will make the image change when the mouse hovers over it.
You can read more about how the value of a Dependency Property is being resolved on MSDN.
<Image.Resources>
<Style TargetType="{x:Type Image}">
<!-- Set the initial source in the style so the trigger can change it -->
<Setter Property="Source" Value="{Binding Converter={StaticResource SetImgToDG}}" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!-- Hover image -->
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Source" Value="C:\Images\Coil3.png"/>
</Trigger>
</Style.Triggers>
</Style>
</Image.Resources>