How do I fill the button background with a circle on click - c#

I want to be able to click my button and on the click trigger I want the background to fill up with a circle, much like how a materialistic button would. I know there is a library for this but I'd much rather develop my own because I want to learn.
This is what it would look like when you click, rather than when you move the mouse out of it.
I've tried playing around with the style of the button, trying to make some animation using storyboards but I can't seem to figure it out.
<Style TargetType="{x:Type Button}">
<Setter Property="Background" Value="Blue"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Transparent"/>
</Trigger>
<EventTrigger RoutedEvent="Click">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard BeginTime="00:00:00"
RepeatBehavior="Forever"
AutoReverse="True"
Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)">
<ColorAnimation From="Black" To="Red" Duration="0:0:0.1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
When I click the button I want the background to fill up starting from a circle shape (the button shouldn't be circle shaped), filling up the rest of the button, what I am seeing now is just a fading color of the entire thing which is not what I was expecting.

Here is an example of such an effect.
I just used a Rectangle, not a Button, for simplicity. But you surely can apply this technique to any control.
The events MouseEnter and MouseLeave are used here, but you can replace them with click events or whatever you need.
<Rectangle Width="150" Height="150" Stroke="Black" StrokeThickness="1">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard Duration="0:0:1">
<!-- we just scale the brush in this animation -->
<DoubleAnimation From="0" To="2" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Transform).(ScaleTransform.ScaleX)"/>
<DoubleAnimation From="0" To="2" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Transform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard Duration="0:0:1">
<DoubleAnimation From="2" To="0" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Transform).(ScaleTransform.ScaleX)"/>
<DoubleAnimation From="2" To="0" Storyboard.TargetProperty="(Rectangle.Fill).(DrawingBrush.Transform).(ScaleTransform.ScaleY)"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
<Rectangle.Fill>
<!-- the rectangle's fill is a brush which can be scaled -->
<DrawingBrush>
<DrawingBrush.Transform>
<!-- the initial scale values are 0, so we don't see the fill -->
<ScaleTransform ScaleX="0" ScaleY="0" CenterX="75" CenterY="75"/>
</DrawingBrush.Transform>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="MediumBlue">
<GeometryDrawing.Geometry>
<EllipseGeometry RadiusX="150" RadiusY="150" Center="75,75" />
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>

Related

MouseEnter MouseLeave in c#

I have problem, while writing a program for drawing figures from a text file. My program is currently reading figures from a text file and drawing them on the canvas, but I have problem with MouseEnter and MouseLeave Events.
I would like the polygon to change colour if there is the mouse over it. How can I do this?
The app is written in WPF, using the Canvas control.
You could use event triggers for this. For example:
<Canvas>
<Canvas.Resources>
<Style TargetType="Polygon">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1"
Storyboard.TargetProperty="(Polygon.Fill).(SolidColorBrush.Color)"
To="Yellow"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1"
Storyboard.TargetProperty="(Polygon.Fill).(SolidColorBrush.Color)"
To="Blue"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Canvas.Resources>
<Polygon Fill="Blue" Canvas.Left="100" Canvas.Top="50">
<Polygon.Points>
<Point>0,0</Point>
<Point>20,0</Point>
<Point>25,5</Point>
<Point>20,20</Point>
<Point>0,20</Point>
<Point>0,0</Point>
</Polygon.Points>
</Polygon>
</Canvas>

Activate Storyboard on Visibility Changed

Currently I have an Image that I pulse when it is loaded. I want to rather activate the Storyboard when I change the Visibility of the Image. But I see that Image.Triggers have to be EventTriggers.
Which event do I need to hook into?
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="MandateErrorImage"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.1" Duration="0:0:0.5"
AutoReverse="True" RepeatBehavior="0:0:2" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
In WPF there is an event UIElement.IsVisibleChanged but is a CLR event, not a routed event, therefore in EventTrigger can not be used.
In this case use IsVisible property in DataTrigger like this:
<Window.Resources>
<Style x:Key="AnimationImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=IsVisible}"
Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="1.0" To="0.1"
Duration="0:0:0.5"
AutoReverse="True"
RepeatBehavior="0:0:2" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Image Name="TestImage"
Style="{StaticResource AnimationImageStyle}"
Source="Enter.jpg"
Width="400"
Height="400" />
</Grid>
If you want to animate on a DependencyProperty or bound value you will need to create a Style for your image and put the animation in the style.
The following Style will perform your animation when the Visibility of your image is set to Visible:
<Style x:Key="FlashingImageStyle" TargetType="{x:Type Image}">
<Style.Triggers>
<Trigger Property="Visibility" Value="Visible">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.1" Duration="0:0:0.5"
AutoReverse="True" RepeatBehavior="0:0:2" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>

Polygon Animation won't work in c#

I am having a small Problem in C#. I want to have a Polygon I drew in WPF to be animated on hover.
I successfully drew the polygon like this:
<Polygon Fill="#FF767676" Points="0,8,12,0,12,16" Margin="30" Style="{DynamicResource BackAndForth}"/>
I then defined a style
<Style x:Key="BackAndForth" TargetType="{x:Type Polygon}">
<Setter Property="Opacity" Value="0.6" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" From="0.6" To="1" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Opacity" From="1" To="0.6" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
Somehow this won't work. The setter property in line 2 works. But somehow the animation won't get triggered. I already looked it up but polygons have a IsMouseOver Property.
The exact same code works perfecty on buttons (with a proper target type).
Any ideas what I am missing?

How to animate multiple Path elements in WPF

I have a collection of glyphs that are in form of WPF <Path> elements.
Something like this:
<Grid>
<Path Data="..." Height="33.333" Stretch="Fill" Width="33.334"/>
<Path Data="..." Height="33.333" Stretch="Fill" Width="33.334"/>
<Path Data="..." Height="33.333" Stretch="Fill" Width="33.334"/>
<Path Data="..." Height="33.333" Stretch="Fill" Width="33.334"/>
</Grid>
These are just image or icon glyphs. I'm trying to find a way to switch or flip between these various Path elements so that it looks like an animation. I'm pretty new to WPF and have tried looking for examples but couldn't find anything similar here or elsewhere on the web. The closest example I found was erasing one <Image> element with another using Storyboard and DoubleAnimation but I can't figure out how to apply it to <Path>.
I'm basically trying to find a way to show one path element and hide all other paths, wait a second, show next path element and hide all other, and so on, to make it look like a flip animation.
I would appreciate if someone can post a simple example or point me in the right direction. Thanks.
Alright give this a try. Note that each Path will get its own Storyboard. So if you have 4 Paths, you get 4 Storyboards.
<Path>
<Path.Style>
<Style TargetType="{x:Type Path}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="00:00:1"
BeginTime="00:00:1"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path>
<Path.Style>
<Style TargetType="{x:Type Path}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0" To="1"
Duration="00:00:1"
BeginTime="00:00:2"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path>
<Path.Style>
<Style TargetType="{x:Type Path}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0" To="1"
Duration="00:00:1"
BeginTime="00:00:3"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
<Path>
<Path.Style>
<Style TargetType="{x:Type Path}">
<Setter Property="Opacity" Value="0"/>
<Style.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity"
From="0"
To="1"
Duration="00:00:1"
BeginTime="00:00:4"
AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
Notice how we're using the FrameworkElement.Loaded event to trigger the animation. You can use this event on virtually any UI element. Each storyboard changes the opacity from 0 (invisible) to 1 (completely visible) in 1 second (you can change this using the Duration property). Also, the BeginTime property is different for each storyboard, this is required to make sure the items are animated one after another. Finally, we set the AutoReverse property to make sure the Paths are disappeared (i.e. the animation is reversed). This should give you the idea.

Load all the effect of storyboard until it's finish

I have an image which when pressed by user, the opacity will fade until value 0. But the effect only continues if user press and hold the image. Is there a possible way to change the code to: When user press, and without holding the press, the opacity fading effect will stay? I wish to do it in XAML.
<EventTrigger RoutedEvent="Button.Click" SourceName="press">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource showA}"/>
</EventTrigger.Actions>
</EventTrigger>
<Button Grid.Column="5" Command="{Binding Path=PressC}" CommandParameter="dot" Style="{StaticResource TransparentButton}">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image Name="image5" Source="/W;component/Images/t.png" Height="100" />
<Image Name="pressed5" Source="/W;component/Images/T.png" Height="100" Width="200" Margin="-23,-136,-21,0" Visibility="Hidden" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="pressed5" Storyboard.TargetProperty="Opacity" Duration="0:0:1.5" From="1" To="0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Setter Property="Panel.ZIndex" Value="999"/>
<Setter TargetName="pressed5" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Can you show your full xaml? Because Image does not have IsPressed property and it is not clear how it works for you.
Similar code for button works as expected:
<Button Background="Aquamarine">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1.5" From="1" To="0"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
And for Image it works too with EventTrigger:
<Image Source="d:\123.png">
<Image.Style>
<Style TargetType="Image">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:1.5" From="1" To="0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Image.Style>

Categories