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>
Related
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>
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?
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.
I have multiple points and I want to draw lines connecting that points with WPF, but I want to see them drawing slowly, and I need to do that programmatically, how can I do that?
Thanks.
You can try something like this:
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetName="MyLine">
<DoubleAnimation Storyboard.TargetProperty="X2" To="100" Duration="0:0:5"/>
<DoubleAnimation Storyboard.TargetProperty="Y2" To="100" Duration="0:0:5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Line X1="10" Y1="10" X2="20" Y2="20" Stroke="Black" Name="MyLine"/>
</Grid>
When you click on the line, you'll see it grow. You can attach starting this storyboard to whatever event or code you want, I just used a mousedown for demonstration purposes.
If you want to draw multiple lines, you can do something like this:
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Line1" Storyboard.TargetProperty="X2" To="100" Duration="0:0:5"/>
<DoubleAnimation Storyboard.TargetName="Line1" Storyboard.TargetProperty="Y2" To="100" Duration="0:0:5"/>
<DoubleAnimation Storyboard.TargetName="Line2" Storyboard.TargetProperty="X2" To="200" Duration="0:0:5" BeginTime="0:0:5"/>
<DoubleAnimation Storyboard.TargetName="Line2" Storyboard.TargetProperty="Y2" To="0" Duration="0:0:5" BeginTime="0:0:5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Grid.Triggers>
<Line X1="10" Y1="10" X2="10" Y2="10" Stroke="Black" Name="Line1"/>
<Line X1="100" Y1="100" X2="100" Y2="100" Stroke="Black" Name="Line2"/>
</Grid>
And, of course, it's quite possible to construct these storyboards on the fly if you can't declare them ahead of time in XAML.
I currently have the XAML:
<Grid Name="WindowGrid">
<Grid Height="66" HorizontalAlignment="Stretch" Margin="0" Name="ControlsGrid" VerticalAlignment="Bottom" Background="#B4000000" />
</Grid>
What I want is when the mouse enters the window (or even WindowGrid, preferably), the ControlGrid slides up, and vice versa (when the cursor leaves, it slides down). I have little experience in WPF/XAML, having most experience in WinForms. I understand there is a way to do this with storyboards/triggers, but the examples I've seen are too confusing.
Use event triggers to perform this:
<Grid Name="WindowGrid">
<Grid.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ControlsGrid"
Storyboard.TargetProperty="(Grid.Height)"
From="0"
To="66"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="ControlsGrid"
Storyboard.TargetProperty="(Grid.Height)"
From="66"
To="0"
Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<!--
This is a sample content to demostrate animation;
Without it 'WindowGrid' will be collapsed.
-->
<ListBox />
<Grid Margin="0" Name="ControlsGrid" VerticalAlignment="Bottom" Background="#B4000000" />
</Grid>