I got a button, that display an image.
I want to add, to this image, an animation, so that it will blink (so the user can't ignore it).
So I tried this in the style.xaml :
<Style x:Key="WarningIcon" TargetType="Button">
<Setter Property="Height" Value="30"/>
<Setter Property="Width" Value="30"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid>
<Image Source="../images/im_warning.png" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Visibility">
<Setter.Value>
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetProperty="(Button.Visibility)"
Duration="5:0:0.5"
RepeatBehavior="Forever"/>
</Storyboard>
</Setter.Value>
</Setter>
</Style>
But it doesn't work.
What kind of animation, and setter should I add to make the image blinking, so basically, appear and desappear?
I do not find any example that match with my research.
Thank you.
You should start animation after defining it. Another thing is that probably Opacity will look better:
<Style
...
<Style.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)"
BeginTime="0:0:0" Duration="0:0:0.5"
From="1.0" To="0.0" RepeatBehavior="Forever" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
...
</Style>
Related
This question already has answers here:
Set button background style in wpf
(2 answers)
Closed 3 years ago.
I am trying to add a background color to a button whenever it is clicked and restoring to its original color after some time. I tried to create a ResourceDictionary.xaml and added my style set and added its reference to a XAML page. Seems something is wrong in my code. If I add the style directly into the button tags, it works.. But not via ResourceDictionary . Please help.
ResourceDictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FantasyPlay">
<Style TargetType="Button">
<Setter Property="Background" Value="Gainsboro" />
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" From="Orange" To="Gainsboro" Duration="0:0:0.50" AutoReverse="True" />
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" From="Gainsboro" To="Orange" Duration="0:0:0.1" AutoReverse="True" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
MyXAML:
I have referenced it like
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
Good day, let try this
<Trigger Property="IsPressed" Value="True">
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard AutoReverse="True" >
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" Duration="0:0:0"/>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)" To="Orange" Duration="0:0:0.50"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
WPF controls have a template.
The button's template does various things, one of which is a mouseover effect. That will interfere with your styling.
Here's a style which works similarly to yours but replaces the template of buttons so you can see the effect when the mouse is over it.
I've used red rather than Gainsboro so this might not be a total cut and paste solution but is to get you started.
<Style TargetType="Button">
<Setter Property="Background" Value="Red"/>
<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>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
To="Orange"
Duration="0:0:1"
AutoReverse="True"
FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Obviously, this replaces what you have in your resource dictionary. Keep a copy of your original first.
I am using the Material Design for my WPF Project and I now want to set a background color for the hover state of a button.
As seen in the code, the implementation is made with a ProgressBar, Ripple and Border.
If I try to overwrite the style, i end up having a invisible Button:
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource MaterialDesignRaisedButton}">
<Setter Property="Background"
Value="{StaticResource MainColorSolidBrush}" />
<Setter Property="Foreground"
Value="{StaticResource TextColorLightSolidBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Triggers>
<!--Hover-->
<Trigger Property="IsMouseOver"
Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="{StaticResource SubColor}"
FillBehavior="HoldEnd"
Duration="{StaticResource HoverStartDuration}" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"
To="{StaticResource MainColor}"
FillBehavior="Stop"
Duration="{StaticResource HoverEndDuration}" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So do I have to reimplement the original style from the package and add a Hover?
You cannot "override" only a part of a template. It has to be defined as a whole which means that you should copy the MaterialDesignRaisedButton style from GitHub and edit it as per your requirements, by for example adding additional setters to the IsMouseOver trigger.
I am designing a ListView and I want to change its border color when it is focused, IsFocused property dosen't seem to work for ListView. Is there any property similar to IsFocused for Listview?
<Style x:Key="{x:Type ListView}" TargetType="ListView">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="BorderBrush" Value="{StaticResource EnabledListViewBorder}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListView}">
<Border x:Name="Border"
Background="Transparent"
Padding="{TemplateBinding Padding}"
BorderBrush="{StaticResource EnabledListViewBorder}"
BorderThickness="1">
<ScrollViewer Style="{DynamicResource ListViewColumnHeaderScrollViewer}">
<ItemsPresenter />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsGrouping" Value="True">
<Setter Property="ScrollViewer.CanContentScroll" Value="False" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DiabledListViewBorder}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource DiabledListViewBorder}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard Duration="0:0:0:1" AutoReverse="False">
<ColorAnimation
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" From="Red" To="Red"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="LostFocus">
<BeginStoryboard>
<Storyboard AutoReverse="False" Duration="0:0:0:1">
<ColorAnimation
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" From="Green" To="Green"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
I have updated the question with my Sourcecode with the solution provided but the Border Color isn't changing. What am i missing here.
You can use Style.Triggers to handle GotFocus and LostFocus events.
<ListView.Style>
<Style TargetType="ListView">
<Style.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard Duration="0:0:0:1" AutoReverse="False">
<ColorAnimation
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" From="Red" To="Red"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="LostFocus">
<BeginStoryboard>
<Storyboard AutoReverse="False" Duration="0:0:0:1">
<ColorAnimation
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" From="Green" To="Green" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ListView.Style>
Update:
If you have rewritten the ControlTemplate, then delete Style.Triggers part and move EventTriggers from it to the ControlTemplate.Triggers. Additionally you have to set Storyboard.TargetName="Border".
<EventTrigger RoutedEvent="LostFocus">
<BeginStoryboard>
<Storyboard AutoReverse="False" Duration="0:0:0:1" Storyboard.TargetName="Border" >
<ColorAnimation
Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
FillBehavior="HoldEnd" From="Green" To="Green" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
For ListBox IsFocused not working because focus goes to ItemsPresenter that contains ListBoxItems. So focus go to ItemsPresenter that is inside the ListBox. I got workaround that you subscribe event MouseDown and inside it do Focus for ListView, then the trigger starts working.
Let me know if it works for you
I'm developing a C# WPF application and try to rotate a button or his content to animate a refreshing state.
Therefor I extended my button style with a DataTrigger and bind to a property of my ViewModel.
But when I start the application and change the property, nothing happens. What did I miss?
Here some code snippets of the button:
<Button Style="{StaticResource MenuButtonStyle}"
Command="{Binding RefreshCommand}">
<Viewbox>
<Path Data="M1.1212257,9.3630001L6.5977538,11.580556 4.2506914,12.856734C5.4929478,15.192778 7.9304001,16.795777 10.761055,16.795777 13.75407,16.795777 16.324983,15.014366 17.488389,12.45831L19.643999,12.45831C18.371294,16.144636 14.875176,18.804999 10.761055,18.804999 7.1745365,18.804999 4.0586705,16.782776 2.4753525,13.820294L0,15.164176z M10.760896,0C14.30653,1.3528629E-07,17.389073,1.977851,18.989344,4.8840143L21.333,3.5363943 20.353317,9.3630001 14.824021,7.2771222 17.239375,5.8891636C15.988099,3.5858327 13.567544,2.0091001 10.760896,2.0091001 7.7688711,2.0091001 5.1979985,3.7902967 4.0345705,6.3461806L1.879,6.3461806C3.1517664,2.6600806,6.6478317,1.3528629E-07,10.760896,0z"
Stretch="Uniform" Fill="{StaticResource IconColor}"/>
</Viewbox>
</Button>
and the property of the ViewModel:
private bool _isRefreshing = false;
public bool IsRefreshing
{
get { return _isRefreshing; }
set
{
_isRefreshing = value;
OnPropertyChanged("IsRefreshing");
}
}
My button style looks like:
<Style x:Key="MenuButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="5"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Width" Value="32"/>
<Setter Property="Height" Value="32"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsRefreshing}" Value="true">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(RotateTransform.Angle)"
From="0"
To="360"
Duration="0:0:8"
RepeatBehavior="Forever"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard FillBehavior="Stop">
<DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(RotateTransform.Angle)"
To="0"
Duration="0:0:0"
/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
Assuming that DataContext of the Button is set accordingly and it has access to IsRefreshing property and you're not setting LayoutTransfom of the Button to RotateTransform so there's nothing to animate. Add another setter to you Style
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="0"/>
</Setter.Value>
</Setter>
I am trying to add animation on mouse hover to my control template set up for buttons in my wpf application
Here is my code:
<Style x:Key="scanButtonActive" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="3,3,0,0" BorderBrush="#575757" BorderThickness="0,6,0,0" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" Cursor="{TemplateBinding Cursor}">
<ContentPresenter x:Name="ScanButton">
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation From="#6d6e6e" To="#b2b2b2" Duration="0:0:1" Storyboard.TargetName="ScanButton" Storyboard.TargetProperty="Background"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation From="#b2b2b2" To="#6d6e6e" Duration="0:0:1" Storyboard.TargetName="ScanButton" Storyboard.TargetProperty="Background"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Padding" Value="7, 3, 7, 3" />
<Setter Property="Margin" Value="0, 0, 0, 10" />
<Setter Property="Background" Value="#6d6e6e" />
<Setter Property="Foreground" Value="#ffffff" />
<Setter Property="Height" Value="100"/>
<Setter Property="Width" Value="250"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
However I get the following error when hovering over a button:
Cannot resolve all property references in the property path Background.
How do I fix this?
There are a few things wrong.
First ContentPresenter does not have a Background property. You might set the Background of the Border control instead.
Second, Background is of type Brush, but a ColorAnmation animates a Color, so you should change the property path to Background.Color.
Third (for completeness), you should explicitly assign a SolidColorBrush to the Background property, which is guaranteed to be modifiable.
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border" ...>
...
</Border>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
To="#b2b2b2" Duration="0:0:1"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
To="#6d6e6e" Duration="0:0:1"
Storyboard.TargetName="border"
Storyboard.TargetProperty="Background.Color"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
...
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#6d6e6e"/>
</Setter.Value>
</Setter>
</Style>
Please note also that you do not have to set the animation's From values explicitly.
Try using the following code instead:
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation From="#6d6e6e" To="#b2b2b2" Duration="0:0:1"
Storyboard.TargetName="ScanButton"
Storyboard.TargetProperty="Control.Background"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation From="#b2b2b2" To="#6d6e6e" Duration="0:0:1"
Storyboard.TargetName="ScanButton"
Storyboard.TargetProperty="Control.Background"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>